c - 内核线程执行更多通信工作时出现不希望的延迟
问题描述
我们开发了一个内核模块,其行为基本上类似于有线通信流量(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()
插入additional时ping时间会减少,或者增加sleep时间?这是否意味着 200-500 us 不足以处理所有挂起的软中断工作,并且较低的软中断被饿死了?添加额外的效果是否与schedule()
通过增加睡眠时间让其他人做更多的工作相同?
内核版本为 4.1.38,配置为 NO_HZ,PREEMPT = y。
解决方案
推荐阅读
- sql - Oracle SQL - 周一从周五、周六和周日以及休息时间提取前一天的数据
- typescript - 如何在将值限制为已知集合的同时推断地图的类型?
- java - Intellij 高亮显示错误,但代码可以正确编译和运行
- shell - 尝试通过 ftp 发送 zip 文件时找不到命令
- python - 通过 Python 脚本将对象数组附加到现有 JSON 文件中
- form-recognizer - 表单识别器无效模型状态
- ios - iOS 上的 Firebase 身份验证失败(Unity、Xcode)
- redux - 在 Redux 中从组件向 Action Creator 传递数据
- c# - C# 如何将错误附加到 1 个单个消息框中?
- ios - 通过 data.nba.net 访问 API 时遇到问题