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交易是成功的。

同时,我可以看到来自其他驱动程序的 printk 消息。串行控制台仍然有效。它在 Android 上,如果我使用“top”,我可以看到 system_server 占用了大约 95% 的 CPU。杀死 system_server 可以使 wait_for_completion_timeout 立即返回。

所以我的问题是用户空间应用程序(system_server)可以做什么来使内核“wait_for_completion_timeout”不被唤醒?

谢谢!

4

2 回答 2

2

wait_for_completion_timeout 仅保证当 (i) 完成发生或 (ii) 超时到期时,等待条件的线程将变为“可运行”。
之后,调度程序的工作就是调度该线程并将其状态从“可运行”更改为“运行”。线程本身(或完成框架)不负责使线程可运行,这是调度程序的工作。
正如您所指出的,system_server 消耗了 95% 的 cpu,因此很难安排完成线程。这就解释了为什么线程没有被安排。

于 2012-11-22T00:26:21.647 回答
0

嗯,我有点想通了。在 CFS 调度中,在 enqueue_entity 中,它在某些条件下执行“vruntime += min_vruntime”,而在 dequeue_entity 中,它在某些条件下执行相反的操作。但是,这些并不总是成对执行。所以在一些未知的情况下,当min_vruntime 很大时,vruntime 会变得很大,所以任务会被放到rbtree 的右边,很长一段时间都不会被调度。我不确定从根本原因解决此问题的最佳方法是什么,我所做的是在 enqueue_entity 中进行破解,如果我发现 vruntime>min_vruntime 并且该函数被称为 WAKEUP,我总是设置 vruntime=min_vruntime,因此任务将被放在 rbtree 的相对左侧。我使用的内核版本是 2.6.37 有人对如何以更好的方式修复此问题有建议吗?

于 2012-12-11T23:02:21.187 回答