2012-11-21 817 views
2

我正在處理i2c-omap驅動程序的一個奇怪問題。我不確定問題是否在其他時間發生,但是當我嘗試關閉系統時發生了大約5%的問題。 在系統關機期間,我通過I2C寫入PMIC中的某些寄存器。在i2c-omap.c中,我可以看到調用線程正在等待wait_for_completion_timeout,超時值設置爲1秒。我可以看到稱爲「完整」的IRQ(我在完成後添加了printk)。但是,在「完成」被調用之後,wait_for_completion_timeout沒有返回。相反,它在返回之前最多需要5分鐘。 wait_for_completion_timeout的返回值爲正數,表示沒有超時。整個I2C交易成功了。Linux內核的wait_for_completion_timeout未完全喚醒

與此同時,我可以看到來自其他驅動程序的printk消息。串口控制檯仍然可以工作。它在Android上,如果我使用「top」,我可以看到system_server佔用了大約95%的CPU。 kill system_server可以立即返回wait_for_completion_timeout。

所以我的問題是用戶空間應用程序(system_server)可以做什麼來使內核「wait_for_completion_timeout」不被喚醒?

謝謝!

+0

你能粘貼相關的代碼嗎? – Harman

+0

事情是我不知道什麼是「有關」。代碼調用wait_for_completion並且大部分時間完成。這很少發生。 :( –

回答

2

wait_for_completion_timeout只保證等待條件的線程在(i)完成時或(ii)超時到期時變爲「可運行」。
之後,調度程序調度該線程並將其狀態從「可運行」更改爲「正在運行」。線程本身(或完成框架)不負責使線程可運行,這是調度程序的工作。
正如您所指出的那樣,system_server佔用了95%的cpu,因此使完成線程難以計劃。這解釋了爲什麼線程沒有得到預定。

+0

這是有道理的,我只是想知道什麼可能需要很長時間才能完成(根據我的經驗,最長可達5分鐘)另一件事讓我想到雖然system_server需要95個CPU,但其他驅動程序發出的printk消息仍然顯示,串行控制檯仍然可以工作,我也可以運行其他用戶應用程序,比如logcat或top。所以很難想象除了等待的內核驅動程序之外,所有這些仍然可以調度。 –

0

嗯,我有點想通了。 在CFS調度中,在enqueue_entity中,它在某些情況下執行「vruntime + = min_vruntime」,而在dequeue_entity中,它在某些情況下執行相反操作。但是,這些並不總是成對執行。所以在一些未知的情況下,當min_vruntime非常大時,vruntime會變得非常大,所以這個任務會被放到rbtree的右邊,而且不會很長時間。 我不知道什麼是從根本原因來解決這個問題的最佳方法,我所做的是在enqueue_entity中進行破解,如果我發現vruntime> min_vruntime並且爲WAKEUP調用函數,我總是設置vruntime = min_vruntime,因此任務將被放到樹的相對左側。 我正在使用的內核版本是2.6.37 任何人都有一個關於如何更好地解決這個問題的建議?