内核线程执行更多通信工作时的不希望的延迟

时间:2018-11-28 07:17:09

标签: c linux-kernel scheduling preemption

我们已经开发了一个内核模块,其功能基本上类似于有线通信流量(eth,...)-WiFi桥接器。它定期将传入的有线数据转发到WiFi,反之亦然。该系统由两个运行相同内核模块的设备组成。在某些情况下,我们会遇到不希望的延迟。

该模块启动一个基本上执行以下操作的内核线程:

while(1) {
    schedule()
    do_bridge_work()
    usleep_range(200, 500)
}

在正常操作期间,top命令显示:

CPU:   0% usr  19% sys   0% nic  60% idle   0% io   0% irq  19% sirq 
Load average: 1.03 1.06 1.01 1/54 491
PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
491    2 root        DW     0   0%  29% [bridge_thread]
3      2 root        SW     0   0%  10% [ksoftirqd/0]

激活诊断后,线程还将发送其他诊断有线eth数据包。在此模式下,一侧到另一侧的设备ping操作从5-6毫秒变为45-900毫秒。 top然后显示:

CPU:   0% usr  25% sys   0% nic  50% idle   0% io   0% irq  24% sirq 
Load average: 1.06 1.07 1.01 1/54 491
PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
491    2 root        DW     0   0%  35% [bridge_thread]
3      2 root        SW     0   0%  14% [ksoftirqd/0]

如果在schedule()之前插入了另外的usleep_range(),或者如果增加了睡眠时间,则可以大大减少等待时间。我想我已将其范围缩小,以得出RX softirq无法获得处理传入流量(NET_RX_SOFTIRQ所需的调度时间的结论。这是基于这样一个事实,即传输数据包的时间非常好。

我的问题是:

1:为什么ping时间会由于do_bridge_work()中的更多工作(更多的处理和额外的数据包传输)而增加。 NET_RX_SOFTIRQ可能会饿死吗?

2:为什么在插入其他schedule()或增加睡眠时间时ping时间会减少?这是否意味着200-500 us不足以处理所有待处理的softirq,而较低的softirq却挨饿了?添加其他schedule()的效果是否与其他方法一样,通过增加睡眠时间来完成更多工作?

内核版本为4.1.38,配置为NO_HZ,PREEMPT = y。

0 个答案:

没有答案