中断亲和性是什么
中断亲和性决定某个 IRQ 由哪些 CPU 处理:内核为每个中断号维护一个 CPU 掩码,中断发生后只在掩码允许的核上执行处理程序。网卡多队列的每个队列各有一个独立 IRQ,因此可以逐队列指定不同的核。手工绑定的价值是让中断处理(尤其软中断)与业务线程错开或集中到专用核上,减少对延迟敏感任务的干扰;接口在 /proc/irq/<n>/ 下的 smp_affinity(十六进制掩码)与 smp_affinity_list(核列表)两个文件。
基本信息
| 查看分布 | /proc/interrupts(每核计数)、/proc/irq/<n>/smp_affinity_list |
|---|---|
| 设置方式 | 向 smp_affinity_list 写入核列表,如 2-3 |
| 权限要求 | root 或对 /proc/irq 有写权限 |
| 两种表示 | smp_affinity 十六进制掩码(1=CPU0,2=CPU1),smp_affinity_list 直接写核号 |
| 限制 | 部分中断(如 per-CPU 中断)不允许改亲和,写入会报错 |
| 持久化 | 运行期设置重启丢失,需 udev 规则、启动脚本或发行版网络配置固化 |
典型使用场景
- 网卡多队列分流:把各队列中断分给不同核,配合应用线程让收发在同一核完成,提升缓存命中
- 把存储控制器中断绑到 NUMA 本地节点,避免跨节点内存访问
- 延迟敏感服务:把中断从业务核上挪走,减少业务线程被抢占
- 排查单核 si 偏高:先看 /proc/interrupts 的计数分布,确认是哪个中断压在哪个核
- 验证手动方案是否被 irqbalance 覆盖,作为停用 irqbalance 后的落地步骤
查看与绑定
查看与绑定
grep -iE 'eth|nvme' /proc/interrupts # 找到设备各队列的 IRQ 号与每核计数
cat /proc/irq/40/smp_affinity_list # 当前允许处理的核列表
cat /proc/irq/40/smp_affinity # 同一掩码的十六进制表示,注意两者换算关系
echo 2-3 | sudo tee /proc/irq/40/smp_affinity_list # 绑定到 CPU2-3
cat /proc/irq/40/smp_affinity_list # 立即复核写入结果
watch -n1 'grep -i eth /proc/interrupts' # 观察计数是否按预期落在目标核上怎么看分布
| 位置 | 字段 | 判读 |
|---|---|---|
| /proc/interrupts 表头 | CPU0 CPU1 … | 各列对应各 CPU 的中断计数 |
| 设备行 | 如 eth0-TxRx-3 | 编号表示队列序号,多队列要逐个处理 |
| smp_affinity_list | 如 2-3 | 可直接读写的核列表,最直观 |
| smp_affinity | 如 0000000c | 十六进制掩码,1=CPU0、2=CPU1,换算易错 |
多队列网卡每个队列一个中断,只绑一个队列等于把该队列的流量压到单核,反而更集中。先用 ethtool -l <网卡> 确认队列数,再按「队列数 = 处理核数」规划绑定关系。
写入 smp_affinity_list 用的是核号(十进制、可用区间写法),写入 smp_affinity 用的是十六进制掩码,两者混淆是最常见的低级错误:向 mask 文件写 2-3 会直接报错或写入失败。