/proc/interrupts不能查看中断响应延迟——它仅统计各cpu上中断触发累计次数,无任何时间信息;真实延迟需用cyclictest测调度干扰、trace-cmd抓handler耗时、irqsoff tracer查关中断问题,三者协同且必须在rt或低延迟内核下进行。

/proc/interrupts 不能查看硬件中断响应延迟——它只存累计触发次数,不记录任何时间信息。真实延迟必须用 cyclictest 暴露调度干扰、用 trace-cmd 抓单次 handler 耗时、用 irqsoff tracer 排查内核关中断问题,三者缺一不可,且需在 RT 内核或低延迟内核下才有意义。
为什么 /proc/interrupts 完全无法反映延迟
执行 cat /proc/interrupts 看到的数字(如 45: 1234567 0 0 0 PCI-MSI-edge eth0-rx-0)只是自启动以来该中断在各 CPU 上被触发的总次数。哪怕某次处理花了 300μs,这个文件里也完全体现不出来。
- 数值突增但无对应流量?大概率是硬件误报或驱动 bug,不是“忙”,而是“错”
- 数值为 0?不代表设备没工作——网卡启用 NAPI 或轮询模式(
ethtool -C eth0 rx off)后中断计数归零,但收包照常 - 虚拟化环境里出现
IR-PCI-MSI前缀,说明 IRQ 编号已与物理引脚解耦,不能按传统编号理解
用 cyclictest 测中断对实时线程的实际影响
cyclictest 不测纯硬件中断响应时间,但它能反映中断真实干扰程度:高优先级实时线程被中断抢占后恢复执行的延迟,这才是业务感知到的“卡顿”根源。
- 安装:
sudo apt install rt-tests(Debian/Ubuntu)或sudo yum install rt-tests(RHEL/CentOS) - 基础命令:
cyclictest -t1 -p99 -i1000 -l10000(单线程、SCHED_FIFO 优先级 99、间隔 1000μs、运行 10000 次) - 加中断干扰测试:
taskset -c 0 cyclictest -t1 -p99 -i1000 -l10000 & ping -f 192.168.1.1,观察Max Latency是否突增 - 延迟值受中断 handler 耗时、锁竞争、内存带宽等共同影响,它不区分原因,只告诉你“这里出问题了”
用 trace-cmd 定位具体中断 handler 耗时
当 cyclictest 显示异常延迟,下一步必须确认是哪个中断在拖慢系统。关键看 irq_handler_entry 到 irq_handler_exit 的 delta 时间(单位纳秒)。
- 确认内核支持:
grep CONFIG_IRQSOFF_TRACER /boot/config-$(uname -r)输出应为y或m - 抓 5 秒数据:
sudo trace-cmd record -e irq:irq_handler_entry -e irq:irq_handler_exit -T 5 - 分析结果:
sudo trace-cmd report | grep -A5 -B5 "eth0\|nvme",快速筛选目标设备相关行 - 重点关注
delta字段:超过 100μs 就值得怀疑——常见原因是驱动在中断上下文中做memcpy、调用可能阻塞的函数、或持有自旋锁太久 - 别用
perf record -e irq:*:它不保证入口/出口配对,采样精度也不够算真实 handler 耗时
用 irqsoff tracer 测内核关中断时间
某些卡顿并非来自外部中断,而是内核自身长时间关中断(比如在 spinlock 区域或 critical section 中)。这时 irqsoff tracer 才是直接证据。
- 启用追踪:
echo irqsoff > /sys/kernel/debug/tracing/current_tracer && echo 1 > /sys/kernel/debug/tracing/tracing_on - 复现问题后停掉:
echo 0 > /sys/kernel/debug/tracing/tracing_on - 查看结果:
cat /sys/kernel/debug/tracing/trace,找最长的关中断区间及其调用栈 - 注意:该 tracer 对性能有明显开销,仅用于短时定位,不能长期开启
真正有意义的“硬件中断响应延迟”从来不是单一数值,而是由中断触发、CPU 响应、handler 执行、下半部处理、软中断调度等多个环节叠加而成。最容易被忽略的是:即使 delta 很小,如果 effective_affinity 和 smp_affinity_list 不一致,说明 irqbalance 正在动态干预,实测结果会漂移;另外,所有工具在非 RT 内核下测出的延迟,对实时业务基本没有参考价值。











