不能只靠isolcpus,因其仅限制普通进程调度,不控制硬件中断分发;网卡中断仍可能随机送达任意cpu,导致软中断ksoftirqd在非目标核运行,需配合smp_affinity绑定irq、停irqbalance、配置rcu_nocbs等参数协同生效。

CentOS 7 修改网卡中断绑定到指定 CPU 核心,本质是控制软中断(softirq)和硬件中断(IRQ)的 CPU 亲和性。这在高吞吐或低延迟场景(如 DPDK、NFV、高性能数据库)中很关键——但直接改错地方会导致中断不响应、网卡丢包甚至服务不可用。
为什么不能只靠 isolcpus 就完事?
isolcpus 只限制内核调度器把普通进程放到哪些 CPU 上运行,它不控制中断分发。网卡产生的硬件中断(如 irq/230)仍可能被送到任意在线 CPU,再由该 CPU 处理软中断(如 NET_RX)。
常见错误是:加了 isolcpus=1,2,3 后发现 top -p $(pgrep ksoftirqd/0) 依然在 CPU 0 上狂跑——因为软中断默认跟硬中断所在 CPU 绑定,而硬中断没动。
怎么查网卡对应的中断号?
先确认网卡名(比如 eth0 或 ens33),再查它的中断:
cat /proc/interrupts | grep -i eth0
输出类似:
230: 12456789 0 0 0 PCI-MSI-edge eth0-TxRx-0 231: 9876543 0 0 0 PCI-MSI-edge eth0-TxRx-1 232: 2345678 0 0 0 PCI-MSI-edge eth0-TxRx-2
每一行开头数字就是 IRQ 编号(230、231、232)。注意:多队列网卡每个 RX/TX 队列对应一个 IRQ,要全部处理。
怎么把中断绑到特定 CPU?
使用 smp_affinity 写入十六进制掩码(bitmask),每位代表一个 CPU。例如想把 IRQ 230 绑到 CPU 1(编号从 0 开始),掩码是 0x2(二进制 0010):
echo 2 > /proc/irq/230/smp_affinity
更稳妥的做法是用十六进制(避免十进制歧义):
echo 0x2 > /proc/irq/230/smp_affinity
批量操作示例(绑所有 eth0 相关 IRQ 到 CPU 1):
for i in $(grep -l "eth0" /proc/irq/*/name 2>/dev/null | xargs -I{} dirname {} | xargs -I{} basename {}); do echo 0x2 > /proc/irq/$i/smp_affinity; done
⚠️ 注意:smp_affinity 文件只读时说明中断由 irqbalance 管理,需先停掉它:systemctl stop irqbalance,否则写入会被覆盖。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
怎么让软中断也固定到某核?
硬中断绑定了,软中断(ksoftirqd/N)默认还在原 CPU 跑。要强制软中断在指定核上处理,得配合 rcu 和 net 子系统参数:
编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 行末尾追加:
rcu_nocbs=1,2,3 net.core.dev_weight=64
其中 rcu_nocbs=1,2,3 把 RCU callbacks 卸载到 CPU 1/2/3,间接降低软中断负载;dev_weight 控制每轮软中断处理包数,防止单次耗时过长。
然后更新 GRUB 并重启:
grub2-mkconfig -o /boot/grub2/grub.cfg && reboot
重启后验证:
cat /proc/irq/*/smp_affinity_list —— 看是否全为期望 CPU 号
watch -n1 'cat /proc/softirqs | grep NET' —— 观察 NET_RX 增长是否集中在目标 CPU
实际生效的关键点不在“配了多少项”,而在顺序和依赖:先停 irqbalance,再写 smp_affinity,再调内核参数,最后验证。漏掉任意一环,都可能看起来配了却没效果。










