先用 nmcli device status 确认网卡名(如 enp1s0f0),再 grep -i "enp1s0f0" /proc/interrupts 找到对应 irq 编号(如 42);若无结果,用 ethtool -i 查驱动名后 grep 驱动名;再通过 /proc/irq/42/smp_affinity_list 和 effective_affinity 验证并设置 cpu 绑定,同时停用 irqbalance、检查 numa 节点、启用多队列。

怎么用 /proc/interrupts 找出网卡对应的 IRQ 编号
直接查 /proc/interrupts 是唯一可靠起点,nmcli 和 ip link 都不提供 IRQ 信息。关键不是“有没有中断”,而是“哪个 IRQ 属于你的网卡”:
- 先确认网卡设备名:运行
nmcli device status,找状态为connected的ethernet类型设备(如enp1s0f0) - 再执行
grep -i "enp1s0f0\|eth0" /proc/interrupts(把设备名替换成你的真实名),输出中类似这样的行就是目标:42: 1234567 0 0 0 890123 0 0 0 IR-PCI-MSI 32768-edge enp1s0f0-rx-0 - 第一列数字
42就是 IRQ 编号;末尾带-rx-、-tx-的说明启用了多队列,每个后缀对应一个独立 IRQ - 若 grep 没结果,试试驱动名:
ethtool -i enp1s0f0 | grep driver得到i40e或mlx5_core,再用grep i40e /proc/interrupts
如何检查当前 IRQ 绑定在哪些 CPU 上
拿到 IRQ 编号后,必须立刻验证亲和性设置是否生效——很多单核瓶颈问题就卡在这一步:
- 优先读
/proc/irq/42/smp_affinity_list(把42换成你的 IRQ 号),输出是十进制 CPU 编号列表,例如0,1,2,3表示允许跑在这 4 个核上 - 如果只输出
0,说明硬绑定在 CPU 0,这就是单核瓶颈的直接证据 - 对比
/proc/irq/42/effective_affinity,它显示内核实际执行的绑定;若和smp_affinity_list不一致,大概率是irqbalance在后台覆盖了你手动写的值 - 检查
irqbalance状态:systemctl is-active irqbalance,若为active,它会周期性重置亲和性,必须先停用:sudo systemctl stop irqbalance
手动分配 IRQ 到指定 CPU 核心的实操要点
写入前不校验条件,轻则无效,重则网卡失联或触发内核警告:
- 确认目标 CPU 未被隔离:运行
cat /proc/cmdline,若含isolcpus=,避开被隔离的核(比如isolcpus=1,2,那就别选 CPU 1 或 2) - 写入值必须合法:用
/proc/irq/42/smp_affinity_list接口更安全,直接写十进制编号,例如echo "0,2,4,6" | sudo tee /proc/irq/42/smp_affinity_list - 不要用
smp_affinity(十六进制掩码),不同架构位宽不同(x86 是 64 位,ARM 可能更宽),容易因掩码长度错位导致只绑到 CPU 0 - 某些驱动(如
mlx5_core)只响应smp_affinity_list,写smp_affinity会静默失败 - 写入后立刻验证:
watch -n 1 'grep enp1s0f0 /proc/interrupts',观察各 CPU 列计数是否开始均匀增长
为什么改完还是只打在一个 CPU 上
最常被忽略的三个现实约束:
-
irqbalance服务重启后自动恢复默认策略,必须用sudo systemctl disable irqbalance彻底禁用,不能只 stop 一次 - NUMA 架构下,网卡物理直连的 CPU 节点才有最低延迟;用
lspci -vv -s $(ethtool -i enp1s0f0 | grep bus-info | awk '{print $2}') | grep NUMA查节点,优先把 IRQ 绑到同节点 CPU - 即使 IRQ 分散了,软中断
NET_RX仍会在触发它的那个 CPU 上执行——所以必须同步启用网卡多队列:ethtool -L enp1s0f0 combined 8(值不超过ethtool -l enp1s0f0显示的最大数)











