直接看 /proc/interrupts 就能知道每个 IRQ 编号被触发次数,但需拆解:首列为 IRQ 编号,后续各列为对应 CPU 触发计数,末列为设备标识(如 eth0、PCI-MSI);数值为 0 不代表设备空闲,可能启用 NAPI 或轮询模式;仅总数不足判断异常,须结合 watch 看增量、smp_affinity_list 查绑定、trace-cmd 抓 handler 耗时(delta >100μs 需警惕)。

直接看 /proc/interrupts 就能知道每个 IRQ 编号被触发了多少次,但“具体”两个字意味着你不能只扫一眼总数——得拆开看谁在打、打在哪颗 CPU、打得多快、每次花了多久。
怎么看 /proc/interrupts 里每一行的真实含义
执行 cat /proc/interrupts 后,每行结构是:IRQ编号 + 各 CPU 列计数 + 设备/控制器标识。例如:
42: 1245678 9023 0 11234 PCI-MSI 0000:03:00.0
这表示 IRQ 42 在 CPU0 上触发了 124 万次,CPU1 是 9 千次,CPU2 是 0 次,设备是 PCIe 地址 0000:03:00.0(通常是网卡或 NVMe)。最后一列不是人名,是内核注册时填的标签,eth0、nvme0n1、i915 这类最可信;IO-APIC 或 IR-PCI-MSI 表示用了中断重映射,IRQ 编号已和物理引脚脱钩,别按老经验猜硬件。
- 数值为 0 不代表设备闲着——启用 NAPI 或轮询(如
ethtool -C eth0 rx off)后,硬中断计数归零,但流量照常走软中断 - 某行全为 0?先确认是否真没触发,还是被屏蔽或未启用(比如 BIOS 关了某 PCIe 设备的 MSI)
- 看到
cascade或rescheduling这类词,属于内核内部中断,一般不用管;timer和irqbalance相关的要小心,它们本身不干活,但可能掩盖真实瓶颈
怎么快速定位“谁在猛打中断”
光看静态总数容易误判。重点不是“总次数高”,而是“增长快、分布偏、无对应负载”。
- 用
watch -n 1 'cat /proc/interrupts | grep -E "(eth|nvme|usb)"'实时盯关键设备,观察某列是否每秒跳增数百以上 - 按设备聚合统计:
awk '{print $(NF)}' /proc/interrupts | sort | uniq -c | sort -nr | head -10,排第一的未必是问题源——可能是正常高吞吐设备(如 10G 网卡),得结合增量判断 - 查某设备绑了哪些 IRQ:
grep eth0 /proc/interrupts | awk '{print $1}',再拿这个数字去查亲和性,避免漏掉多队列网卡的多个 IRQ - 虚拟机里看到大量
IR-IO-APIC?说明 KVM 正做中断注入,此时/proc/interrupts的 IRQ 编号对宿主机无物理意义,得去 guest 里查
为什么不能只信 /proc/interrupts 的数字
它只记“触发次数”,不记“每次花了多久”“有没有堆积”“是否被延迟处理”。系统卡顿但 /proc/interrupts 数值平稳?那问题大概率出在 handler 耗时上。
- 必须用
trace-cmd record -e irq:irq_handler_entry -e irq:irq_handler_exit -T 5抓单次生命周期,分析时盯delta字段(单位纳秒),持续 >100μs 就该怀疑驱动在中断上下文里做了 memcpy、spin_lock 长时间持有、或调了慢速 I/O -
perf record -e irq:*不推荐——它不保证入口/出口事件配对,采样精度也不够,算不出真实 handler 耗时 - 确认内核支持:
grep CONFIG_IRQSOFF_TRACER /boot/config-$(uname -r)必须返回y或m,否则 trace-cmd 会失败 - 数值暴涨但没进程在跑?八成是硬件异常(网卡丢包重试、PCIe 设备误报)或驱动 bug,不是负载高
怎么查中断绑在哪个 CPU 上
别碰 smp_affinity(十六进制掩码),x86 和 ARM 位宽不同,写错直接导致中断不触发。统一用 smp_affinity_list——输出是十进制 CPU 编号,人眼可读,也兼容所有架构。
- 查网卡中断绑定:
grep eth0 /proc/interrupts | awk '{print $1}' | xargs -I{} sh -c 'echo {}:/proc/irq/{}/smp_affinity_list' | while read l; do echo "$l: $(cat ${l##*:} 2>/dev/null)"; done - 如果
/proc/irq/*/effective_affinity和smp_affinity_list不一致,说明irqbalance或内核自动管理正在干预,此时手动改smp_affinity_list可能被覆盖 - 某 IRQ 在
/proc/interrupts里 CPU0 计数极高,但smp_affinity_list显示允许 CPU0-CPU3,说明问题不在绑定,而在设备本身(比如网卡没开 RSS、驱动没实现多队列)
真正麻烦的从来不是“怎么查”,而是查完发现数值合理、分布均匀、handler 耗时也正常,但系统还是抖——这时候得怀疑是不是软中断(/proc/softirqs)或 RCU callback 堆积,或者中断只是表象,根子在内存带宽、PCIe 退频、甚至 BIOS 设置里关了某个节能特性。


















