Linux多核下绑定硬件中断到不同 CPU(IRQ Affinity)

本文介绍了Linux系统中中断处理的概念,包括中断的作用、中断号以及中断控制器(如APIC)。讲解了如何通过调整IRQAffinity将硬件中断绑定到特定CPU,以优化多核系统的性能。通过`/proc/interrupts`和`/proc/irq/XXX/smp_affinity`文件进行观察和设置,手动分配中断处理以减轻CPU负担。最后,讨论了合理绑定中断对于提升系统吞吐能力和性能的重要性。
摘要由CSDN通过智能技术生成

Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)

中断定义

中断是一种比较好的CPU 和硬件沟通的方式,还有一种方式叫做轮询(polling),就是让 CPU 定时对硬件状态进行查询然后做相应处理,这种方式非常浪费(CPU)的时间,所以中断是硬件主动的方式,比轮询(CPU 主动)更有效一些。

每个硬件设备都中断,那么如何区分不同硬件呢?不同设备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?系统上的每个硬件设备都会被分配一个IRQ 号,通过这个唯一的 IRQ 号就能区别是来自谁了。

在计算机里,中断是一种电信号,由硬件产生,并直接送到中断控制器(如 8259A)上,然后再由中断控制器向 CPU 发送信号,CPU 检测到该信号后,就中断当前的工作转而去处理中断。然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。现在来看一下中断控制器,常见的中断控制器有两种:可编程中断控制器 8259A 和高级可编程中断控制器(APIC),中断控制器应该在大学的硬件接口和计算机体系结构的相关课程中都学过。传统的 8259A 只适合单 CPU 的情况,现在都是多 CPU 多核的 SMP 体系,所以为了充分利用 SMP 体系结构、把中断传递给系统上的每个 CPU 以便更好实现并行和提高性能,Intel 引入了高级可编程中断控制器(APIC)。

光有高级可编程中断控制器的硬件支持还不够,Linux 内核还必须能利用到这些硬件特质,所以只有 kernel 2.4 以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为SMP IRQ Affinity.

如何使用

系统上的中断是怎么分配在 CPU 上的,很显然 CPU0 上处理的中断多一些

cat /proc/interrupts
            CPU0       CPU1
   0:         61          0   IO-APIC-edge      timer
   1:         15         18   IO-APIC-edge      i8042
   4:       4650          0   IO-APIC-edge
   6:          2          0   IO-APIC-edge      floppy
   8:          1          0   IO-APIC-edge      rtc0
   9:          0          0   IO-APIC-fasteoi   acpi
  12:         57          6   IO-APIC-edge      i8042
  14:          0          0   IO-APIC-edge      ata_piix
  15:        133       6919   IO-APIC-edge      ata_piix
  16:       1700       1900   IO-APIC-fasteoi   vmwgfx, snd_ens1371
  17:      36636          0   IO-APIC-fasteoi   ehci_hcd:usb1, ioc0
  18:         75          0   IO-APIC-fasteoi   uhci_hcd:usb2
  19:         67      18689   IO-APIC-fasteoi   ens33
  24:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  25:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  26:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  27:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  28:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  29:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  30:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  31:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  32:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  33:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  34:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  35:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  36:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  37:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  38:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  39:          0          0   PCI-MSI-edge      PCIe PME, pciehp
  40:          0          0   PCI-MSI-edge      PCIe PME, pciehp

为了把部分中断转移到 CPU1 上,ehci_hcd:usb1, ioc0的中断转到 CPU1 上呢?先查看一下 IRQ 17 中断的 smp affinity,看看当前中断是怎么分配在不同 CPU 上的(ffffffff 意味着分配在所有可用 CPU 上)

[root@kolla ~]# cat /proc/irq/17/smp_affinity
00000000,00000000,00000000,00000001
[root@kolla ~]# cat /proc/irq/17/smp_affinity_list 
0
以上可知中断使用的是cpu0.

在进一步动手之前我们需要先停掉 IRQ 自动调节的服务进程,这样才能手动绑定 IRQ 到不同 CPU,否则手动绑定做的更改将会被自动调节进程给覆盖掉。如果想修改 IRQ 17 的中断处理,绑定到第2个 CPU(CPU1):

systemctl stop irqbalance
systemctl disable irqbalance
echo 1 > /proc/irq/17/smp_affinity_list   ##就是指cpu1
或者
echo "2" > /proc/irq/17/smp_affinity   ###2也是代指cpu1,不过需要进行二进制到16转换
                                     ###之后会讲如何计算 SMP IRQ Affinity

查看结果

[root@kolla ~]# cat /proc/irq/17/smp_affinity
00000000,00000000,00000000,00000002

过段时间在看 /proc/interrupts,是不是 17 在 CPU1 上的中断增加了、在 CPU0 上的中断没变?不断打印 /proc/interrupts 就会发现 ehci_hcd:usb1, ioc0 在 CPU0 上的中断数始终保持不变,而在 CPU1 上的中断数是持续增加

watch -d cat    /proc/interrupts
Every 2.0s: cat /proc/interrupts                                                                                                                   Tue Nov 16 22:20:06 2021

            CPU0       CPU1
   0:         61          0   IO-APIC-edge	timer
   1:         15         18   IO-APIC-edge	i8042
   4:	   10665          0   IO-APIC-edge
   6:          2          0   IO-APIC-edge	floppy
   8:          1          0   IO-APIC-edge	rtc0
   9:          0          0   IO-APIC-fasteoi   acpi
  12:         57          6   IO-APIC-edge	i8042
  14:          0          0   IO-APIC-edge	ata_piix
  15:        133      15721   IO-APIC-edge	ata_piix
  16:       1700       1900   IO-APIC-fasteoi   vmwgfx, snd_ens1371
  17:	   37417         42   IO-APIC-fasteoi   ehci_hcd:usb1, ioc0
  18:         75          0   IO-APIC-fasteoi   uhci_hcd:usb2
  19:         67      28594   IO-APIC-fasteoi   ens33
  24:          0          0   PCI-MSI-edge	PCIe PME, pciehp

作用

在网络非常 heavy 的情况下,对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力;对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。

计算 SMP IRQ Affinity

“echo 2 > /proc/irq/17/smp_affinity”中的 ”2“ 是怎么来的,这其实是个二进制数字,代表 00000010,00000001 代表 CPU0 的话,00000010 就代表 CPU1, “echo 2 > /proc/irq/90/smp_affinity” 的意思就是说把17 中断绑定到 00000010(CPU1)上。所以各个 CPU 用二进制和十六进制表示就是:

               Binary       Hex 
    CPU 0    00000001         1 
    CPU 1    00000010         2
    CPU 2    00000100         4
    CPU 3    00001000         8
    ###cpu0比较特殊,并不是用全0表示,而是00000001,其余cpu则按照正常10进制转2进制进行转换

如果把 IRQ 绑定到 CPU2 上就是 00000100=4:

echo "4" > /proc/irq/17/smp_affinity

如果想把 IRQ 同时平衡到 CPU0 和 CPU2 上就是 00000001+00000100=00000101=5

echo "5" > /proc/irq/17/smp_affinity

需要注意的是,在手动绑定 IRQ 到 CPU 之前需要先停掉irqbalance这个服务,irqbalance 是个服务进程、是用来自动绑定和平衡 IRQ 的:
还有一个限制就是,IO-APIC 有两种工作模式:logicphysical,在 logic 模式下 IO-APIC 可以同时分布同一种 IO 中断到8颗 CPU (core) 上(受到 bitmask 寄存器的限制,因为 bitmask 只有8位长。);在 physical 模式下不能同时分布同一中断到不同 CPU 上,比如,不能让 eth0 中断同时由 CPU0 和 CPU1 处理,这个时候只能定位 eth0 到 CPU0、eth1 到 CPU1,也就是说 eth0 中断不能像 logic 模式那样可以同时由多个 CPU 处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值