在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。kernel 2.4 以后的版本利用可编程中断控制器的特性支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为 SMP IRQ Affinity。
使用前提
需要多核CPU的系统,使用uname -a可以查询是否支持SMP。需要大于等于2.4的Linux 内核 ,使用uname -r可以查询内核版本。相关设置文件,设置/proc/irq/{IRQ}/smp_affinity和/proc/irq/{IRQ}/smp_affinity_list指定了哪些CPU能够关联到一个给定的IRQ源. 这两个文件包含了这些指定cpu的cpu位掩码(smp_affinity)和cpu列表(smp_affinity_list)
绑定网口中断到CPU
smp_affinity主要针对多队列网卡多CPU环境,如网卡支持多队列则可使用SMP irq affinity直接绑定硬中断,要是不支持多队列,那就用RPS解决网络软中断的负载均衡,即单个网卡的软中断分散到多个CPU处理,避免单个CPU负载过大导致性能瓶颈。
手动绑定 IRQ 到不同 CPU,需要先停掉 IRQ 自动调节的服务进程,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。SMP_AFFINITY文件:在/proc/irq/{IRQ}/目录下都有一个smp_affinity文件,这个文件中,所表示的CPU核心以十六进制来表示的。
查找硬件IRQ号:
cat /proc/interrupts
/proc/interrupts中的字段依次是逻辑中断号、中断在各CPU上发生的次数,中断所属父设备名称、硬件中断号、中断触发方式(电平或边沿)、中断名称。
修改/proc/irq/23/smp_affinity
注意smp_affinity这个值是一个十六进制的bitmask,在smp_affinity中哪些位被置1,就是将affinity设置在那个(那些)CPU了。
如:8个逻辑核心,那么CPU#的序列为11111111(从右到左依次为CPU0~CPU7)如果cat /proc/irq/76/smp_affinity的值为:20(20是16进制对应的二进制为:00100000与11111111求与),则76这个IRQ的亲和性为#5号CPU。
每个IRQ的默认的smp affinity在这里:
cat /proc/irq/default_smp_affinity
另外,查看irq在哪个CPU上执行使用:
cat /proc/irq/default_smp_affinity_list
需要设置多个CPU核心时可使用:
//设置1-6core
echo 1-6 > /proc/irq/23/smp_affinity_list
echo 7e > /proc/irq/23/smp_affinity
//设置core1,core6
echo 1,6 /proc/irq/23/smp_affinity_list
echo 42 /proc/irq/23/smp_affinit