Linux 中断和 CPU SMP 亲和性简介
中断是由硬件或软件通过 IRQ(中断请求线)发送的信号。
中断允许键盘、串行卡和并行端口等设备指示它需要 CPU 关注。
一旦 CPU 收到中断请求,CPU 将暂时停止正在运行的程序的执行,并调用一个称为中断处理程序或 ISR(中断服务程序)的特殊程序。
中断服务或中断处理程序可以在位于内存固定地址的中断向量表中找到。处理完中断后,CPU 恢复中断的程序。
在启动时,系统会识别所有设备,并将适当的中断处理程序加载到中断表中。
以下是请求 CPU 关注的两种方式:
- 基于中断
- 基于轮询
所有基于 Linux 的操作系统都是中断驱动的。
当我们按下键盘上的一个键时,键盘会告诉 CPU 一个键已被按下。但是 CPU 可能正忙于处理来自 RAM、系统时钟、NIC 卡的一些东西,可能是视频或 PCI 总线。在这种情况下,键盘会在分配给该硬件的 IRQ 线上放置一个电压,在这种情况下是 [键盘]。这种电压变化作为来自设备的请求,表示设备有需要处理的请求。
/proc/interrupts 文件
在 Linux 机器上,文件 /proc/interrupts 包含有关正在使用的中断以及处理器被中断的次数的信息
# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 3710374484 0 0 0 IO-APIC-edge timer
1: 20 0 0 0 IO-APIC-edge i8042
6: 5 0 0 0 IO-APIC-edge floppy
7: 0 0 0 0 IO-APIC-edge parport0
8: 0 0 0 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
12: 240 0 0 0 IO-APIC-edge i8042
14: 11200026 0 0 0 IO-APIC-edge ide0
51: 61281329 0 0 0 IO-APIC-level ioc0
59: 1 0 0 0 IO-APIC-level vmci
67: 19386473 0 0 0 IO-APIC-level eth0
75: 94595340 0 0 0 IO-APIC-level eth1
NMI: 0 0 0 0
LOC: 3737150067 3737142382 3737145101 3737144204
ERR: 0
MIS: 0
在上面的文件中:
- 第一列是 IRQ 号。
- 第二列表示 CPU 内核中断了多少次。在上面的示例中,计时器是中断名称 [系统时钟],3710374484 是 CPU0 被中断的次数。I8042 是键盘控制器,用于控制 PC 中的 PS/2 键盘和鼠标。
- 对于像 rtc [Real time clock] CPU 没有被中断的中断。RTC 存在于电子设备中以跟踪时间。
- NMI 和 LOC 是用户无法访问/配置的系统上使用的驱动程序。
IRQ号决定了需要CPU处理的中断的优先级。
较小的 IRQ 数值意味着较高的优先级。
例如,如果 CPU 同时接收到来自键盘和系统时钟的中断。CPU 将首先为系统时钟提供服务,因为它的 IRQ 编号为 0。
- IRQ 0 — 系统定时器(不能更改);
- IRQ 1 — 键盘控制器(不能更改)
- IRQ 3 — 串行端口 2 的串行端口控制器(与串行端口 4 共享,如果存在);
- IRQ 4 — 串行端口 1 的串行端口控制器(与串行端口 3 共享,如果存在);
- IRQ 5 — 并行端口 2 和 3 或声卡;
- IRQ 6 — 软盘控制器;
- IRQ 7 — 并行端口 1。如果打印机不存在,它用于打印机或任何并行端口。
对于像操纵杆这样的设备,CPU 不会等待设备发送中断。由于用于游戏的操纵杆和操纵杆的移动会很快,因此非常适合使用轮询并检查设备是否需要注意。这种方法的缺点是 CPU 可能会进入忙等待状态,多次检查设备。
与此相关的是,在 Linux 中正确处理信号也很重要。
硬件中断
以上讨论的所有场景都是硬件中断的示例。
硬件中断进一步分为两大类:
- 不可屏蔽中断 [NMI]:顾名思义,这些类型的中断不能被 CPU 忽略或抑制。MNI 通过单独的中断线发送,它通常用于严重的硬件错误,如内存错误、指示风扇故障的硬件陷阱、温度传感器故障等。
- 可屏蔽中断:这些中断可以被 CPU 忽略或延迟。中断屏蔽寄存器屏蔽在高速缓存控制器的外部引脚上触发的中断。通过写入 0 设置位,禁用引脚上的中断触发
软件中断
当 CPU 执行可能导致 CPU [ALU 单元] 本身出现异常情况的指令时,会产生这些中断。
例如,不可能将一个数除以零,会导致除零异常,导致计算机放弃计算或显示错误信息。
文件 /proc/stat 也是/proc 文件系统的文件部分,其中包含有关系统内核统计信息的信息,也包含一些中断信息。
# cat /proc/stat
cpu 17028082 5536753 5081493 1735530500 42592308 90006 479750 0
cpu0 5769176 1170683 1495750 403368354 39406374 90006 284864 0
cpu1 3714389 1451937 1186134 444082258 1084780 0 64876 0
cpu2 3791544 1471013 1211868 443988514 1056981 0 64764 0
cpu3 3752971 1443119 1187740 444091373 1044172 0 65244 0
intr 417756956 --- Output Truncated
intr 行显示了自引导时间以来服务的中断计数。第一列是服务的所有中断的总数。随后的每一列都是特定中断的总数。
SMP_AFFINITY
对称多处理是由多个处理器处理程序。
smp_affinity 文件保存一个 IRQ 号的中断关联值。与每个 IRQ 号关联的 smp_affinity 文件存储在 /proc/irq/IRQ_NUMBER/smp_affinity 文件中。文件中的值存储在代表系统中所有 CPU 内核的十六进制位掩码中。smp_affinity 适用于具有启用 IO-APIC 的设备驱动程序的设备。
例如,以太网驱动程序的 smp_affinity 条目如下所示:
grep eth0 /proc/interrupts
67: 23834931 0 0 0 IO-APIC-level eth0
eth0 的 IRQ 号为 67,对应的 smp_affinity 文件位于:
cat /proc/irq/67/smp_affinity
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
值“000000001”的十进制等效值为“1”。即所有与以太网驱动程序相关的中断都将由CPU0 处理。
我们可以通过更改特定控制器的 smp_affinity 文件中的值或使用 irqbalance 来手动更改处理器亲和性。
IRQ 余额
Irqbalance 是一个 Linux 实用程序,它在计算机系统的处理器内核上分配中断,有助于提高性能。
Irqbalance 的目标是在省电和最佳性能之间找到平衡点。
如果您的系统上没有安装 irqbalance,请使用 yum 安装它,如下所示。
# rpm -qa | grep irqbalance
irqbalance-0.55-15.el5
# yum search irqbalance
# yum install irqbalance.x86_64
启动 irqbalance 服务:
service irqbalance start
以下是安装了 irqbalance 的 Linux 机器的示例输出。我们可以看到中断现在正在 CPU 之间分配。
# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 950901695 0 0 0 IO-APIC-edge timer
1: 13 0 0 0 IO-APIC-edge i8042
6: 96 10989 470 0 IO-APIC-edge floppy
7: 0 0 0 0 IO-APIC-edge parport0
8: 1 0 0 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
12: 109 1787 0 0 IO-APIC-edge i8042
15: 99 84813914 0 0 IO-APIC-edge ide1
51: 17371 0 46689970 0 IO-APIC-level ioc0
67: 1741 0 0 225409160 PCI-MSI eth0
83: 0 0 0 0 PCI-MSI vmci
NMI: 0 0 0 0
LOC: 950902917 950903742 950901202 950901400
ERR: 0
MIS: 0
Irqbalance 在具有多核处理器的系统上特别有用,因为中断通常只由第一个核提供服务。
- 点赞
- 收藏
- 关注作者
评论(0)