一.中断
1.1 中断概念
指CPU在运行期间,由于外部或由预先安排的事件引起的CPU暂时停止正在运行中的程序,然后进入内部或外部的预先安排的事件服务的程序中去,服务完毕后再返回继续运行被暂时中断的程序。
1.2 中断上下部
在一个特定中断的时候,内核会执行一个函数,该函数叫中断服务例程。要是既想中断服务例程运行的快,又想中断例程完成的任务多,我们把中断处理成两部分执行。中断上半部:接收中断立即执行,但有严格的超时限制。中断下半部:允许稍后完成。(下半部只是将任务推迟一点,让他们在不繁忙和中断恢复后继续执行。
1.3 中断上下文
内核态和用户态是操作系统的两种模式,代表着不同的级别。内核态运行在内核空间(最高级别)、用户态运行在用户空间(较低级别)。处理器始终处于三种状态下的一种:
- 内核态:运行进程上下文。
- 内核态:运行中断上下文。
- 用户态:运行用户空间。
由于系统有两种状态,可以通过系统调用在这两种模式之间切换。但用户态和内核态有不同的地址映射,用户进程要传很多变量、参数给内核,内核雅瑶保存用户进程的一些寄存器、变量等,以便系统调用结束后回到用户态继续执行。中断上下文可以理解为硬件传递过来的一些参数和内核需要保存的环境。
二.网卡中断与CPU绑定
2.1 背景
在Linux的网络调优方面,如果你发现网络流量上不去,那么有一个方面需要去查一下:网卡处理网络请求的中断是否被绑定到单个CPU或跟处理其它中断的是同一个CPU。 网卡与操作系统交互的两种方式:
- IRQ:网卡在收到了网络信号之后,主动发送中断到CPU,而CPU将会立即停止处理中断信号。
- DMA:允许硬件在无CPU干预的情况下将数据缓存在指定的内存空间内,在CPU合适的时候才处理。
2.2 问题判定
让IO跑满(比如对于MySQL/MongoDB服务,可以通过客户端发起密集的读操作; 或者执行一个i大文件传送任务),来查明一下是不是某个CPU在一直忙着处理IRQ?使用
mpsta t -P ALL 1
查看
%irq
处理中断的时间占比:
18:20:33 CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
18:20:33 all 0,23 0,00 0,08 0,11 6,41 0,02 0,00 93,16 2149,29
18:20:33 0 0,25 0,00 0,12 0,07 0,01 0,05 0,00 99,49 127,08
18:20:33 1 0,14 0,00 0,03 0,04 0,00 0,00 0,00 99,78 0,00
18:20:33 2 0,23 0,00 0,02 0,03 0,00 0,00 0,00 99,72 0,02
18:20:33 3 0,28 0,00 0,15 0,28 25,63 0,03 0,00 73,64 2022,19
我们可以看到第四个CPU有25.63%的时间都在处理中断。我们接着定位CPU在处理哪些中断,使用
cat /proc/interrupts
命令:
CPU0 CPU1 CPU2 CPU3
0: 245 0 0 7134094 IO-APIC-edge timer
8: 0 0 49 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
66: 67 0 0 0 IO-APIC-level ehci_hcd:usb2
74: 902214 0 0 0 PCI-MSI eth0
169: 0 0 79 0 IO-APIC-level ehci_hcd:usb1
177: 0 0 0 7170885 IO-APIC-level ata_piix, b4xxp
185: 0 0 0 59375 IO-APIC-level ata_piix
NMI: 0 0 0 0
LOC: 7104234 7104239 7104243 7104218
ERR: 0
MIS: 0
从上面可以看到:
eth0
所出发的中断全部都是
CPU0
在处理,而CPU0所处理的中断请求中,主要是eth0和LOC中断。 根据上面
上面
的内容我们可以看到 eth0 的中断号是74,我们看下断号的CPU绑定情况
sudo cat /proc/irq/74/smp_affinity
:
ffffff
0xffffff = ‘0b111111111111111111111111’
说明24个CPU都可以被该中断干扰,我们可以修改这个设置
echo 2 > /proc/irq/74/smp_affinity,
(设置为2表示将该中断绑定到CPU1上,0x2 = 0b10,而第一个CPU为CPU0)。