%si高仅表明软中断处理繁忙,需结合/proc/softirqs(盯net_rx/timer/sched)和/proc/interrupts(查eth0等硬中断分布)交叉验证,再检查msi-x队列数、rps掩码及smp_affinity_list配置,闭环排查中断链路。

看 top 的 %si 列只能粗略定位,不能确认问题根源
执行 top -1 后按 1 显示所有 CPU 核,%si(soft irq)列数值高,只说明该核在处理软中断,但无法区分是 NET_RX、TIMER 还是 SCHED 类型。比如 Cpu1 上 %si 达 48.2%,而 Cpu4 是 0.0%,这明显不均,但原因可能是网卡硬中断全打在 CPU1,也可能是某个进程疯狂触发定时器回调。别直接调参,先查清来源。
用 /proc/softirqs 定位具体软中断类型和分布
运行 cat /proc/softirqs,重点关注三列末尾数字:
-
NET_RX:某核数值比其他核高一个数量级(如 520 万 vs 其他核都在 30 万以内),基本锁定是网卡收包导致的单核软中断堆积 -
TIMER:异常升高常与 cfs_bandwidth 超限、RCU 回调积压或高频 tick 有关,不是网络问题 -
SCHED:飙升多见于短生命周期线程暴增(如 fork-bomb 或 gRPC 高频 stream 创建)
注意:该文件每行末尾对应各 CPU 的累计计数,不是实时速率。要观察变化趋势,可用 watch -n 1 'cat /proc/softirqs | grep NET_RX'。
查 /proc/interrupts 确认硬中断是否扎堆
软中断不均往往源于硬中断绑定失当。执行 grep eth0 /proc/interrupts,观察各 CPU 列数值:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 若所有
eth0-*行只有 CPU0 和 CPU1 有计数,其他核为 0,说明网卡 MSI-X 队列只绑在这两核 - 检查队列数:
ls /sys/class/net/eth0/device/msi_irqs/ | wc -l,输出应 ≥ 物理 CPU 核数;少于核数则硬件不支持充分分散 - 确认 RPS 是否启用:
cat /proc/sys/net/core/rps_cpu_mask,若为空或全 0,RPS 关闭,软中断无法跨核迁移
硬中断没散开,调 net.core.netdev_budget 或改调度策略基本无效。
手动分散 IRQ 亲和性必须按掩码规则写入 smp_affinity_list
不要用十六进制 smp_affinity,改用十进制列表接口更安全:
- 查当前 IRQ 号:
grep eth0 /proc/interrupts | head -1 | awk '{print $1}' | tr -d ':' - 将 IRQ 95 绑定到 CPU2:
echo 2 > /proc/irq/95/smp_affinity_list - 批量绑定多个队列时,确保轮询分配(如 32 个队列分给 8 核,就用
for i in {0..31}; do echo $((i%8)) > /proc/irq/$((95+i))/smp_affinity_list; done)
写错格式(如写成 0x4 却没对应 CPU)会导致中断失效;改完立刻用 watch -n 1 'cat /proc/interrupts | grep eth0' 验证计数是否开始流动。
真正难的是中断链路闭环:硬中断 → RSS/RPS → 软中断 → 应用线程。漏掉任一环,负载就会卡在某处不动。尤其容易忽略的是 RPS 掩码未按 NUMA 节点对齐,或 XPS 发送侧没同步配平。










