irqbalance 会因负载评估失效将多队列网卡中断集中到 CPU0;需停用后手动绑定各 RSS 队列到不同 CPU,并配置 RPS/RFS、关闭 GRO/LRO,最后通过 /proc/softirqs 验证 softirq 均衡。

irqbalance 为什么会让网卡中断全挤在 CPU0 上
默认启用的 irqbalance 在某些内核版本(尤其是 4.x/5.x)或特定硬件上,会错误地将多队列网卡的中断(如 eth0-TxRx-0、eth0-TxRx-1…)全部映射到同一个 CPU 核心(通常是 CPU0),而不是均匀分散。这不是 bug,而是它依赖的负载评估机制失效:softirq 处理延迟、RSS 队列未被识别、或 /proc/interrupts 中中断计数更新滞后,都会导致它“误判”其他核不忙。
常见现象:top -p $(pgrep irqbalance) 看不到明显占用,但 cat /proc/interrupts | grep eth0 显示所有队列中断都集中在 CPU0;同时 watch -n1 'cat /proc/softirqs | grep -E "(NET_RX|NET_TX)"' 显示 CPU0 的 NET_RX 值飙升,而其他核几乎为 0。
停掉 irqbalance 后怎么手动绑定网卡中断
停用 irqbalance 只是第一步,关键是要把每个 RSS 队列中断明确绑定到不同 CPU,且避开系统保留核(如 isolcpus、rcu_nocbs 绑定的核)。
- 先查网卡支持的中断数量:
grep eth0 /proc/interrupts | wc -l(比如 16 个队列) - 查可用 CPU 列表:
nproc和cat /sys/devices/system/cpu/online,排除隔离核 - 逐个写入
smp_affinity_list:echo 0 > /proc/irq/123/smp_affinity_list # 第 1 队列 → CPU0
echo 1 > /proc/irq/124/smp_affinity_list # 第 2 队列 → CPU1
... - 注意:写入前确认该 IRQ 确实属于对应网卡队列(看
/proc/interrupts第二列),避免误绑系统中断
网卡队列数、CPU 数、RPS/RFS 设置要对齐
单纯调中断 affinity 不够,softirq 负载还受上层分流影响。如果网卡队列数(ethtool -l eth0)少于 CPU 数,或者没开 RPS,即使中断分开了,所有包仍可能被送到同一个 softirq 上下文处理。
- 确保
ethtool -l eth0显示的Combined值 ≥ 你打算使用的 CPU 数(如 8 队列配 8 核) - 检查 RPS 是否启用:
cat /sys/class/net/eth0/queues/rx-0/rps_cpus,若为空或全 0,需按 CPU 掩码写入(如 8 核用ff,但更推荐用rps_cpus按队列分别设) - RFS(Receive Flow Steering)建议开启:
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries,并为每个 rx 队列设rps_flow_cnt(如echo 2048 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt) - 关闭 GRO/LRO(
ethtool -K eth0 gro off lro off),避免大包重组集中消耗单核 softirq
验证 softirq 分布是否真的均衡
改完不能只看 /proc/interrupts,必须确认 softirq 实际执行位置。最直接的方法是采样 /proc/softirqs 并观察各列变化速率:
运行 watch -n0.5 'grep -A1 "NET_RX" /proc/softirqs',等 10 秒,看 CPU0–CPU7 对应列是否同步增长(差值
容易忽略的一点:某些主板 BIOS 里有 “Interrupt Remapping” 或 “x2APIC Mode” 选项,若关闭,会导致 smp_affinity_list 写入无效 —— 此时必须进 BIOS 打开 x2APIC,否则手动绑定永远不生效。










