SMP IRQ Affinity与网卡绑定多CPU

转自  https://blog.csdn.net/yue530tomtom/article/details/76095739

参考https://blog.csdn.net/mrbuffoon/article/details/82839096  网卡多队列

       https://www.cnblogs.com/flyfish919/p/7338418.html   网卡多队列

       https://www.cnblogs.com/Bozh/archive/2013/03/21/2973769.html  SMP IRQ affinity

其中最后一篇文档使用netperf对SMP IRQ affinity情况下的TCP小包、TCP大包、UDP小包、UDP打包进行了性能对比测试,有一定参考意义。

名词解释
IRQ: Interrupt ReQuest中断请求,IRQ号决定了需要被CPU处理的优先级。IRQ号越小意味着优先级越高。


SMP:(Symmetric Multi-Processing)对称多处理结构的简称,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。可以理解为系统存在多个完全相同的CPU ,所有CPU共享总线,拥有自己的寄存器。对于内存和外部设备访问,由于共享总线,所以是共享的。 Linux 操作系统多个 CPU 共享在系统空间上映射相同,是完全对等的。


中断:是由硬件或软件发送的一种称为IRQ的信号,是一种CPU与硬件沟通的方式(还有另外一种叫轮询)。中断是一种电信号,由硬件产生,并直接送到中断控制器上,然后再由中断控制器向CPU发送信号,CPU检测到该信号后,就中断当前的工作转而去处理中断。然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。中断分为两个过程,中间以中断控制器作为分隔。上半部分即中断上半部,下半部分为中断下半部。上半部分大部分为所说的硬件中断,下半部分为软中断。 

SMP IRQ affinity
APIC表示高级可编程中断控制器(Advanced Programmable Interrupt Controlle),APIC是SMP体系的核心,通过APIC可以将中断分发到不同的CPU来处理.即将中断绑定CPU或者把中断处理平摊到CPU上,这个过程叫做 SMP IRQ Affinity。

SMP IRQ affinity使用前提
1. 需要多CPU的系统,使用uname -a可以查询是否支持SMP
2. 需要大于等于2.4的Linux 内核 ,使用uname -r可以查询内核版本
3. 相关设置文件,设置/proc/irq/{IRQ}/smp_affinity和/proc/irq/{IRQ}/smp_affinity_list指定了哪些CPU能够关联到一个给定的IRQ源. 这两个文件包含了这些指定cpu的cpu位掩码(smp_affinity)和cpu列表(smp_affinity_list)。


绑定硬件中断到CPU
手动绑定 IRQ 到不同 CPU,需要先停掉 IRQ 自动调节的服务进程,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。 
SMP_AFFINITY文件:在/proc/irq/{IRQ}/目录下都有一个smp_affinity文件,这个文件中,所表示的CPU核心以十六进制来表示的。 
1、查找硬件IRQ号

[root@admin ~]# cat /proc/interrupts
            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
   0:      27541          0          0          0          0          0          0          0   IO-APIC-edge      timer
   1:          9          0          0          0          0          0          0          0   IO-APIC-edge      i8042
   8:          1          0          0          0          0          0          0          0   IO-APIC-edge      rtc0
   9:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   acpi
  12:        109          0          0          0          0          0          0          0   IO-APIC-edge      i8042
  14:          0          0          0          0          0          0          0          0   IO-APIC-edge      ata_piix
  15:   57502472          0          0          0          0          0          0          0   IO-APIC-edge      ata_piix
  16:         69          0          0          0          0          0 1039981547          0   IO-APIC-fasteoi   eth1
  17:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1
  19:         67          0          0          0          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb2
  24:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  25:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  26:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  27:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  28:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  29:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  30:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  31:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  32:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  33:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  34:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  35:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  36:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  37:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  38:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  39:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  40:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  41:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  42:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  43:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  44:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  45:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  46:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  47:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  48:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  49:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  50:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  51:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  52:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  53:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  54:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  55:          0          0          0          0          0          0          0          0   PCI-MSI-edge      pciehp
  56:       4514          0          0          0          0          0          0   10837328   PCI-MSI-edge      vmw_pvscsi
  66:    1051805          0          0          0          0          0          0          0   PCI-MSI-edge      vmci
  67:          0          0          0          0          0          0          0          0   PCI-MSI-edge      vmci
 NMI:          0          0          0          0          0          0          0          0   Non-maskable interrupts
 LOC: 1869449523  197290359  333847185  195402404 1716706473  156640980 3003939114 1708931297   Local timer interrupts
 SPU:          0          0          0          0          0          0          0          0   Spurious interrupts
 PMI:          0          0          0          0          0          0          0          0   Performance monitoring interrupts
 IWI:          0          0          0          0          0          0          0          0   IRQ work interrupts
 RES: 3394823095 1382776074 1674379986  943540239  374079686  184005614  115961174   91412940   Rescheduling interrupts
 CAL:       2223       2424       3990       3988       3990       3979       3977       3484   Function call interrupts
 TLB:     187257     546075     524015     282946     303969     157363     650465     740107   TLB shootdowns
 TRM:          0          0          0          0          0          0          0          0   Thermal event interrupts
 THR:          0          0          0          0          0          0          0          0   Threshold APIC interrupts
 MCE:          0          0          0          0          0          0          0          0   Machine check exceptions
 MCP:      27383      27383      27383      27383      27383      27383      27383      27383   Machine check polls
 ERR:          0
 MIS:          0


2、修改/proc/irq/{IRQ}/smp_affinity 
注意smp_affinity这个值是一个十六进制的bitmask,它和cpu No.序列的“与”运算结果就是将affinity设置在那个(那些)CPU了。(也即smp_affinity中被设置为1的位为CPU No.) 
如:8个逻辑core,那么CPU#的序列为11111111 (从右到左依次为CPU0~CPU7) 

[root@admin ~]# cat /proc/irq/16/smp_affinity
00000000,00000000,00000000,00000040


/proc/irq/16/smp_affinity中的数字是16进制的,“40”转为二进制则为0100 0000, 这说明16号IRQ的亲和性为#6号CPU。 

另外,cat /proc/irq/16/smp_affinity_list可以直接得到16号IRQ的亲和性CPU的十进制数字。

[root@admin ~]# cat /proc/irq/16/smp_affinity_list
6

如果你想设置16号IRQ绑定到多颗CPU,则可以修改 /proc/irq/16/smp_affinity。例如绑定16号IRQ到#5和#6CPU,如下:

[root@admin ~]# echo "00000000,00000000,00000000,00000060" > /proc/irq/16/smp_affinity
[root@admin ~]# cat /proc/irq/16/smp_affinity
00000000,00000000,00000000,00000060
[root@admin ~]# cat /proc/irq/16/smp_affinity_list
5-6

3. 停止irqbalance服务

需要先停掉 IRQ 自动调节的服务进程,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。

[root@admin ~]# service irqbalance status
irqbalance (pid  2569) is running...
[root@admin ~]# service irqbalance stop
Stopping irqbalance:                                       [  OK  ]
[root@admin ~]# service irqbalance status
irqbalance (pid 745) is running...
[root@admin ~]# service irqbalance stop
Stopping irqbalance:                                       [  OK  ]
[root@admin ~]# service irqbalance status
irqbalance is stopped


网卡负载均衡

SMP IRQ affinity主要针对多队列网卡多CPU环境。如何确定网卡是否支持多队列?

[root@localhost ~]# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: 0
TX: 0
Other: 0
Combined: 2 # 这一行表示最多支持设置2个队列
Current hardware settings:
RX: 0
TX: 0
Other: 0
Combined: 1 #表示当前生效的是1个队列

[root@localhost ~]# ethtool -L eth0 combined 2 # 设置eth0当前使用2个队列

要确保多队列确实生效,可以查看文件:

# ls /sys/class/net/eth0/queues/

rx-0  rx-2  rx-4  rx-6  tx-0  tx-2  tx-4  tx-6
rx-1  rx-3  rx-5  rx-7  tx-1  tx-3  tx-5  tx-7

 如上,如果rx数量是设定值,则正确。


使用总结
1、通过手动改变smp_affinity文件中的值来将IRQ绑定到指定的CPU核心上,或者启用irqbalance服务来自动绑定IRQ到CPU核心上。没有启动irqbalance 也没有合理的做手动 irq 绑定的话会有性能问题。手动 irq 只推荐给很 heavy、很特殊的情况,比如带多网卡多硬盘的网络存储服务器,一般机器一般应用还是用irqbalance 省心 
2、在一个大量小包的系统上,irqbalance优化几乎没有效果,而且还使得cpu消耗分配的不均衡,导致机器性能得不到充分的利用,这个时候需要把它给结束掉。 
3、对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力; 
4、对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。 
5、DB可以设置一部分CPU处理硬盘IO,一部分CPU处理网络IO,多网卡服务器可以设置对应CPU对应网卡。当然具体情况看生产情况而定。

发布了87 篇原创文章 · 获赞 64 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/wqfhenanxc/article/details/94434255