/proc/interrupts无法查看中断响应延迟,它仅记录各IRQ自启动以来的触发次数,不含任何时间信息;真实延迟必须用trace-cmd捕获irq_handler_entry和irq_handler_exit事件,通过delta字段(纳秒级)判定单次处理耗时是否超100μs。

直接看 /proc/interrupts 不行,它不存延迟数据
/proc/interrupts 只记录每个 IRQ 自启动以来的触发次数,比如 45: 1234567 0 0 0 PCI-MSI-edge eth0-rx-0,这个 1234567 是累计计数,和时间完全无关。哪怕某次中断处理卡了 500μs,文件里也毫无痕迹。数值突增但没对应流量?大概率是硬件误报或驱动 bug,不是“忙”,而是“错”。
真实硬件中断延迟必须用 trace-cmd 抓 irq_handler_entry 和 irq_handler_exit
要拿到单次中断从到达、被 CPU 响应、到 handler 执行完毕的完整耗时,唯一可靠方式是启用 ftrace 并捕获入口和出口事件:
- 先确认内核支持:
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(单位纳秒),它是irq_handler_exit时间减irq_handler_entry时间;超过100000(即 100μs)就该怀疑驱动在中断上下文中做了 memcpy、调用了可能阻塞的函数、或持有自旋锁太久
别用 perf record -e irq:*——它不保证入口/出口配对,采样精度也不够算真实 handler 耗时。
延迟高不等于中断源有问题,得区分硬中断和软中断
看到系统卡顿,先别急着怪网卡或 NVMe:
- 查硬中断分布:
grep eth0 /proc/interrupts看是否全打在 CPU0 上;如果某列每秒涨几千,而其他列几乎不动,说明绑定失衡,不是延迟高,是“堵车” - 查软中断执行:
cat /proc/softirqs | grep NET_RX,如果 CPU0 的NET_RX计数远高于其他核,且mpstat -P ALL 1显示该核%soft持续 >30%,那瓶颈其实在下半部,不是硬中断响应慢 - 硬中断计数为 0?不代表设备没工作——
ethtool -C eth0 rx off启用轮询后,硬中断归零,但软中断NET_RX照常飙升
cyclictest 测的是业务感知到的延迟,不是纯硬件响应时间
cyclictest 不测芯片级中断响应,它测的是“定时器到期 → 实时线程被调度执行”的延迟,反映中断对调度的实际干扰:
- 安装:
sudo apt install rt-tests(Debian/Ubuntu) - 基础命令:
taskset -c 0 cyclictest -t1 -p99 -i1000 -l10000,观察Max Latency - 加压复现:
stress --vm 1 --vm-bytes 1G & ping -f 192.168.1.1,再跑cyclictest,若Max Latency突增,说明中断处理拖累了实时任务 - 注意:
cyclictest的延迟值受中断 handler 耗时、锁竞争、内存带宽共同影响,它不告诉你哪一行代码出问题,只告诉你“这里出问题了”
真正要定位到具体驱动函数,必须回到 trace-cmd 抓到的 delta 字段——那个纳秒级数字,才是硬件中断延迟的唯一可信证据。其他任何统计总数、百分比、平均值的工具,都只是间接线索。


















