我正在处理i2c-omap驱动程序的一个奇怪问题。我不确定这个问题是否在其他时间发生,但它发生在我试图关闭系统电源的大约5%的时间。在系统断电期间,我通过I2C向PMIC中的一些寄存器写入数据。在i2c-omap.c中,我可以看到调用线程正在等待超时值设置为1秒的wait_for_completion_timeout。我可以看到名为"complete“的IRQ (我在”complete“之后添加了printk )。然而,在调用"complete“之后,wait_for_completion_timeout没有返回。相反,它需要5分钟才能返回。wait_for_completion_timeout的返回值为正,表示没有超时。整个I2C交易都是成功的。
同时,我可以看到来自其他驱动程序的printk消息。而且串行控制台还能正常工作。它是在安卓上的,如果我使用"top“,我可以看到system_server占用了大约95%的CPU。杀死system_server可以让wait_for_completion_timeout立即返回。
所以我的问题是,用户空间应用程序(system_server)可以做些什么来使内核"wait_for_completion_timeout“不被唤醒?
谢谢!
发布于 2012-11-22 08:26:22
wait_for_completion_timeout只保证等待条件的线程在(i)完成发生或(ii)超时到期时变得“可运行”。
在此之后,调度器的任务是调度该线程,并将其状态从"runnable“更改为"running”。线程本身(或完成框架)不负责使线程可运行,这是调度器的工作。
正如您所指出的,system_server消耗了95%的cpu,因此使得完成线程很难被调度。这就解释了为什么线程没有被调度。
发布于 2012-12-12 07:02:21
好吧,我有点想通了。在CFS调度中,在enqueue_entity中,它在某些条件下执行"vruntime += min_vruntime“,而在dequeue_entity中,它在某些条件下执行相反的操作。然而,这些并不总是成对执行的。因此,在一些未知的情况下,当min_vruntime非常大时,vruntime可能会变得非常大,因此任务将被放在rbtree的右侧,并且不会被调度很长一段时间。我不确定从根本上解决这个问题的最好方法是什么,我所做的是在enqueue_entity中进行了一次黑客攻击,如果我发现了vruntime>min_vruntime,并且函数被调用来唤醒,我总是设置vruntime=min_vruntime,因此任务将被放到rbtree的相对左侧。我使用的内核版本是2.6.37,有人建议如何以更好的方式修复这个问题吗?
https://stackoverflow.com/questions/13503888
复制相似问题