我怎样才能找出什么阻止了Linux任务的安排?

我有一个带有多个单线程用户进程的嵌入式Linux系统。 其中一个定期(非常偶然)未能安排,即使有工作在等待它做。 我怎样才能找出什么阻止进程(任务/线程)被安排?

我使用strace -p <pid>来追踪进程的内核调用,当它挂起时,得到这个:

...
ioctl(13, 0x40104604, 0xffff6ecf08)     = 0
_newselect(13, [8 9 10 11 12], [], [], {0, 0}) = 0 (Timeout)
_newselect(13, [8 9 10 11 12], [], [], {0, 0}) = 0 (Timeout)
_newselect(13, [8 9 10 11 12], [], [], {0, 15000}) = 0 (Timeout)
_newselect(13, [8 9 10 11 12], [], [], {0, 19000}) = 1 (in [12], left {0, 705})
read(12, "3$GPZDA,072522.038,06,01,1980,,*"..., 1600) = 32
_newselect(13, [8 9 10 11 12], [], [], {0, 0}) = 0 (Timeout)
_newselect(13, [8 9 10 11 12], [], [], {0, 0}) = 0 (Timeout)
_newselect(13, [8 9 10 11 12], [], [], {0, 15000}

最后一次select()调用(strace输出中的_newselect()在15ms超时后没有返回。 看起来在选择中发生了上下文切换,之后该任务在很长时间(几十秒)内不再运行。 当任务最终恢复时,它再次正常运行。

我使用ftrace启用了内核,并启用了sched_switch跟踪器,并在进程恢复时获得了该输出:

...
<idle>-0     [000] 10876.339906:      0:120:R   + [000]  1385:120:R ems
<idle>-0     [000] 10876.339915:      0:120:R ==> [000]  1385:120:R ems
   ems-1385  [000] 10876.340006:   1385:120:S ==> [000]     0:120:R <idle>
<idle>-0     [000] 10876.340300:      0:120:R ==> [000]  1379:100:R gps
   gps-1379  [000] 10876.340453:   1379:100:R   + [000]  1377:120:R dgs
...

感兴趣的过程是gps (pid 1379),在37秒的非活动时间后,它在第二行中恢复。 (从进程本身的debug printfs中可以知道不活动的持续时间。)请注意,没有“+”行表示任务已经准备就绪 - 我假设发生在37秒前(当然是跟踪不会那么远!)。 相反,任务刚开始运行,没有迹象表明它为什么被阻止。

我试过在使用setpriority(PRIO_PROCESS, <pid>, -20)发生挂机几秒钟后从另一个进程中提升任务的优先级(这就是为什么优先级在上面的跟踪中显示为100,而不是默认的120)但没有什么区别,所以我不认为这个问题是优先关系。

现在可以做什么来找出导致任务暂停的原因? 我不熟悉在内核空间中的调试 - ftrace套件中是否有其他工具可以在单个pid上运行,以查看它在做什么? 任何其他内核调试工具? 我可以在发生问题时识别出问题,但只有在几秒钟后才能发现 - 因此,我可以在此时触发或停止任何数据捕获,但跟踪比前一段时间发生的事件更棘手。

内核版本是2.6.33,如果有帮助的话。 由于各种原因,升级到更高版本并不是一个实际的主张。

任何关于如何进一步调试的建议或建议都非常受欢迎!

链接地址: http://www.djcxy.com/p/84881.html

上一篇: How can I find out what is preventing a Linux task from being scheduled?

下一篇: Linux: Disabling interrupt from interrupt handler