linux多处理器系统 内核中 的 中断处理

多处理器系统正在变得越来越普通,它在带来速度、性能等好处的同时,也带来了新的问题和新的思考。
6.7.1 处理器间中断
在多处理器系统中,操作系统需要在多个处理器间协调操作,这通常是通过处理器间中断(Inter-Processor Interrupt,IPI)实现的。
IPI 是一种特殊的硬件中断,由处理器发出,被其他处理器接收,以便于处理器间通信或同步。
通常并不明确区分 IPI 与设备中断,当一个处理器接收到一个中断时,如果发现另一个处理器处理该中断更加合理,则可以通过 IPI 机制将该中断传递到其他的处理器,实现处理器的负载平衡。
当一个 CPU 想对另一个 CPU 发送中断信号时,就在自己的本地 APIC 的 ICR(Interrupt Command Register,中断命令寄存器)中存放其中断向量,和目标 CPU 拥有的本地 APIC 的标识,触发中断。IPI 中断信号经由 APIC 总线传递到目标 APIC,那个收到中断的 APIC 就向自己所属的 CPU 发送一个中断。
Linux 针对 IA32 的 SMP 系统定义了 5 种 IPI,中断向量号分别为 251~255。
(1)CALL_FUNCTION_VECTOR。发往自己除外的所有 CPU,强制它们执行指定的函数。
(2)RESCHEDULE_VECTOR。使被中断的 CPU 重新调度。
(3)INVLIDATE_TLB_VECTOR。使被中断的 CPU 废弃自己的 TLB 缓存内容。
(4)ERROR_APIC_VECTOR。错误的 APIC 向量,应该从不发生。
(5)SPUROUS_APIC_VECTOR。假的 APIC 向量,应该从不发生。

6.7.2 中断亲和力

中断亲和力(SMP IRQ affinity)是指将一个或多个中断服务程序绑定到特定的 CPU 上运行,内核自2.4 版本开始对此提供支持。
中断亲和力可以通过操作/proc/irq 目录下的文件来控制。对于已经注册中断服务程序的硬件设备,在/proc/irq 目录下存在一个以该中断号命名的目录,该目录下有一个 smp_affinity 文件(SMP 体系结构才有该文件)
,它是一个 CPU 的位掩码,其中的每一位对应于一个 CPU,可以用来设置该中断的亲和力,默认值为 0xffffffff,表明把中断发送到所有的 CPU 上去处理。如果中断控制器不支持 IRQ affinity,则不能改变此默认值。注意不能将其设置为 0x0,即关闭所有 CPU 对该中断的处理。
以网卡(eth1,中断号 44)为例,在具有 8 个 CPU 的服务器上来设置网卡中断的亲和力(参见文件 Documentation\IRQ-affinity.txt)。

[root@moon 44]# cat smp_affinity
ffffffff
[root@moon 44]# echo 0f > smp_affinity
[root@moon 44]# cat smp_affinity
0000000f
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
...
--- hell ping statistics ---
6029 packets transmitted, 6027 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.1/0.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:
44: 0  1785  1785 1783 1783 1 1 0 IO-APIC-level eth1
[root@moon 44]# echo f0 > smp_affinity
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
..
--- hell ping statistics ---
2779 packets transmitted, 2777 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.5/585.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:
44: 1068 1785 1785 1784 1784 1069 1070 1069 IO-APIC-level eth1

 

首先只允许在 CPU 0~3 上处理网卡中断,接着运行 ping 程序,不难发现在 CPU 4~7 上并没有对网卡中断进行处理。然后只在 CPU 4~7 上对网卡中断进行处理,CPU 0~3 不对网卡中断进行任何处理,运行 ping 程序之后,再次查看/proc/interrupts 文件时,不难发现 CPU 4~7 上的中断次数明显增加, 而CPU 0~3 上的中断次数没有太大的变化。
利用中断亲和力,我们可以在多处理系统中均衡各个 CPU 的负载,比如对于具有多个网卡的 SMP 系统,可以将各个网卡的中断信号分别绑定到不同的 CPU 上,从而可以大幅提高系统能够处理的网络通信流量。

6.7.3 中断负载均衡
中断负载均衡是指将重负载 CPU 上的中断迁移到较空闲的 CPU 上进行处理。如果希望系统支持这个功能,必须在编译内核的时候配置 CONFIG_IRQBALANCE 选项。
中断负载均衡的实现代码位于 arch\i386\kernel\io-apic.c 文件。
其中的 balanced_irq_init 函数会进行中断负载均衡模块的初始化,同时会创建一个内核线程 kirqd 用于执行具体的均衡处理。代码如下:

666 static int __init balanced_irq_init(void)
667 {......
703printk(KERN_INFO "Starting balanced_irq\n");
704if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd")))
705return 0;
706printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
......
715 }

而 kirqd 每隔 5s 调用一次 do_irq_balance 函数,进行中断的迁徙.


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值