我有一个运行在中等速度 ARMv7 处理器上的 2.6.35 PREEMPT 内核。大约每 100 - 125 秒一次,某些事情会导致内核无法足够快地处理某些与音频相关的驱动程序以避免欠载。滞留时间通常在 15-30 毫秒的范围内,但也可能更长。目前尚不清楚这种阻塞是否完全在内核中发生,还是可能与以实时优先级 (SCHED_RR, 2) 运行的用户进程的调度有关。
我的猜测是有一个(至少一个)驱动程序在抢占时表现不佳。
用户进程的一些 strace 输出说明了正常和异常行为的某些方面,尽管我不确定如何解释各种时间报告?
正常情况:
0.000518 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL, revents=POLLIN}], 1, 3415) = 1 0.010202 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3404) = 1 0.000585 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3404) = 1 0.000302 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL, revents=POLLIN}], 1, 3404) = 1 0.010706 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3393) = 1 0.000480 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3392) = 1
在 fd6 上轮询输出时不会发生阻塞,当只轮询 fd10 输入时,会发生大约 10 毫秒的阻塞。这在系统调用持续时间和系统调用间隔的报告中都有体现(它们是一致的)。
失败案例(极端例子):
0.000305 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL, revents=POLLIN}], 1, 3543) = 1 0.010730 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3533) = 1 0.000475 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 2, 3532) = 1 0.000329 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL, revents=POLLIN}], 1, 3532) = 1 0.953349 poll([{fd=10, events=POLLIN|POLLERR|POLLNVAL}, {fd=6, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT|POLLERR}], 2, 2578) = 1
请注意,在这种情况下,即使将倒数第二个呼叫记录为耗时 10 毫秒(正常),它也比最后一个呼叫早 953 毫秒。
我可以使用哪些工具来追查罪魁祸首?