要看中断是否在猛打cpu,必须盯住单位时间内的增量而非/proc/interrupts累计总数;用watch -n 1 'grep eth0 /proc/interrupts'观察某列每秒跳变速度,若仅cpu0持续线性上涨而其他核几乎不动,说明是亲和性失衡而非频率过高。

怎么看中断是否在猛打 CPU
只看 /proc/interrupts 里的总数会误判——它不带时间戳,100 万次可能是跑了一年,也可能是过去 1 秒打的。真正要判断“猛不猛”,得盯住单位时间内的增量。
用 watch -n 1 'grep eth0 /proc/interrupts'(把 eth0 换成你实际网卡名,比如 ens33 或 enp0s3)观察某一行某一列(如 CPU0)数字跳变速度:
- 每秒稳定涨 500+,才算高频;涨个位数基本可忽略
- 只有
CPU0在涨,CPU1–CPU7几乎不动 → 不是频率高,是亲和性没调,90% 的“高中断”其实是绑死单核 - 看到
rx-0、tx-1这类后缀,说明开了多队列,有多个 IRQ 可分散;如果只有一行且无后缀,大概率网卡根本没启用 MSI-X - 数值为 0?别急着下结论——
ethtool -C eth0 rx off后硬中断归零,但收包照常(NAPI 轮询模式)
怎么区分硬中断和软中断谁在吃 CPU
/proc/interrupts 和 /proc/softirqs 是两个独立源头,不能互相替代。前者只记硬件 IRQ 触发次数,后者才反映下半部真实负担。
运行 watch -n 1 'cat /proc/softirqs | grep -E "^(NET_RX|TIMER|SCHED):"',重点看单核上 NET_RX 是否线性飙升:
-
NET_RX每秒增长超 10 万次,而硬件中断只涨几百 → NAPI 没生效,或驱动在中断上下文里干了太多事(比如 memcpy 大块数据) -
mpstat -P ALL 1显示某核%soft长期 >30%,再查对应 CPU 在/proc/softirqs中哪一列涨得最快,就能锁定瓶颈类型 -
RES(重调度)、CAL(IPI)、TIMER持续飙升?不是硬件问题,是内核调度或 busy-loop 引起的,别往驱动上扯 - 虚拟化环境里看到
IR-PCI-MSI前缀,IRQ 编号已与物理引脚解耦,不能按传统编号推测负载
怎么确认单次中断到底花了多久
/proc/interrupts 从不记录耗时,哪怕某次 handler 执行了 200μs,文件里也完全体现不出来。真要定位延迟,必须用 trace-cmd 抓入口到出口的 delta。
先确认内核支持:grep CONFIG_IRQSOFF_TRACER /boot/config-$(uname -r) 输出应为 y 或 m;再执行:
trace-cmd record -e irq:irq_handler_entry -e irq:irq_handler_exit -T 5-
trace-cmd report | grep -A5 -B5 "eth0\|nvme"快速筛选目标设备相关行 - 重点关注
delta字段(单位纳秒):超过 100μs 就值得怀疑——常见原因是驱动在中断上下文中做memcpy、调用可能阻塞的函数、或持有自旋锁太久 - 别用
perf record -e irq:*:它不保证入口/出口配对,采样精度也不够算真实 handler 耗时
怎么查中断绑在哪个 CPU 上
中断默认分散,但单核被打满会导致延迟抖动。查亲和性是为了确认是不是“堵在一条道上”,而不是盲目调优。
优先用 smp_affinity_list(输出十进制 CPU 编号,人眼可读),别碰 smp_affinity(十六进制掩码,x86 和 ARM 位宽不同,写错直接导致中断不触发):
grep eth0 /proc/interrupts | awk '{print $1}' | xargs -I{} sh -c 'echo IRQ{}: $(cat /proc/irq/{}/smp_affinity_list 2>/dev/null)'- 查
/proc/irq/*/effective_affinity,如果它和smp_affinity_list不一致,说明irqbalance或内核自动管理正在干预 - NUMA 架构下,网卡 IRQ 应优先绑到直连该网卡的 CPU 节点,用
lscpu和lspci -vv -s $(ethtool -i eth0 | grep 'bus-info' | awk '{print $2}')交叉验证 NUMA node - 某些中断(如 BMC、老 RAID 卡)固件锁定,写入会报
Operation not permitted,先ls -l /proc/irq/<irq_num>/</irq_num>看有没有smp_affinity*文件再动手











