IRQ
什么是IRQ
IRQ的全称是“Interupt ReQuest”,即“中断要求”。 中断其实就是由硬件或软件所发送的一种称为IRQ(中断请求)的信号。 一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。CPU处理完中断后,就会恢复执行之前被中断的程序。
/proc/irq/IRQ#/smp_affinity
(十六进制的值)和/proc/irq/IRQ#/smp_affinity_list
(十进制的值)来决定irq的cpu亲和性。
$ cat /proc/irq/0/smp_affinity_list
0-11 # 0-12号cpu
$ cat /proc/irq/0/smp_affinity
fff # 111111111111
中断的分类
中断有两种,一种是硬中断,一种是软中断。
硬中断
- 非屏蔽中断(Non-maskable interrupts,即NMI):就像这种中断类型的字面意思一样,这种中断是不可能被CPU忽略或取消的。NMI是在单独的中断线路上进行发送的,它通常被用于关键性硬件发生的错误,如内存错误,风扇故障,温度传感器故障等。
- 可屏蔽中断(Maskable interrupts):这些中断是可以被CPU忽略或延迟处理的。当缓存控制器的外部针脚被触发的时候就会产生这种类型的中断,而中断屏蔽寄存器就会将这样的中断屏蔽掉。我们可以将一个比特位设置为0,来禁用在此针脚触发的中断。
软中断
- 这些中断是在CPU执行指令(也就是说在进程正在运行的时候)的时候产生的,因为在执行指令时,CPU(确切的说应是在CPU中的运算器)自身会产生一个异常(此处的异常也可理解为软中断)。例如,一个数字除以0(当然这是不可能的),此时就会导致一个divide-by-zero的异常,从而导致计算机将此计算取消或者显示一个错误的信息。
# 常见irq
IRQ0:系统计时器
IRQ1:键盘
IRQ2:可设置中断控制卡
IRQ3:COM2(串行接口2)
IRQ4:COM1(串行接口1)
IRQ5:未预先配置
IRQ6:磁盘机
IRQ7:并行接口
IRQ8:CMOS/时钟
IRQ9:未预先配置
IRQ10:未预先配置
IRQ11:未预先配置
IRQ12:PS/2鼠标
IRQ13:算术处理器(Arithmetic Processor)
IRQ14:Primary(主)IDE控制器
IRQ15:Secondary(从)IDE控制器
查看cpu 的irq占用情况
第一个要查明的是:是不是某个CPU在一直忙着处理IRQ?
mpstat -P ALL 1
# %irq一列即说明了CPU忙于处理中断的时间占比
查看中断
硬中断
$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 36 0 0 0 IO-APIC-edge timer
1: 43 1869 73 0 IO-APIC-edge i8042
6: 3 0 0 0 IO-APIC-edge floppy
8: 4692 0 0 5822 IO-APIC-edge rtc0
9: 1 0 0 0 IO-APIC-fasteoi acpi
11: 0 0 0 0 IO-APIC-fasteoi uhci_hcd:usb1, virtio3
12: 1301 0 400 3559 IO-APIC-edge i8042
14: 2260953 4209306 4806839 5228353 IO-APIC-edge ata_piix
15: 0 0 0 0 IO-APIC-edge ata_piix
40: 0 0 0 0 PCI-MSI-edge virtio0-config
41: 2080652731 412633462 1190395724 502753008 PCI-MSI-edge virtio0-input.0
42: 17553 15456 24657 17208 PCI-MSI-edge virtio0-output.0
43: 0 0 0 0 PCI-MSI-edge virtio1-config
44: 772059213 1257140278 913795736 1245588174 PCI-MSI-edge virtio1-input.0
45: 4991 9253 20623 34285 PCI-MSI-edge virtio1-output.0
46: 0 0 0 0 PCI-MSI-edge virtio2-config
47: 6138729 20923397 37 285 PCI-MSI-edge virtio2-requests
48: 0 0 0 0 PCI-MSI-edge virtio4-config
49: 54278 93116 130890 242970 PCI-MSI-edge virtio4-input.0
50: 2 1 1 5 PCI-MSI-edge virtio4-output.0
NMI: 0 0 0 0 Non-maskable interrupts
LOC: 1633376140 1298855431 1048376331 937827285 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 0 0 0 0 Performance monitoring interrupts
IWI: 187 225 902 359 IRQ work interrupts
RTR: 0 0 0 0 APIC ICR read retries
RES: 334501392 285786398 257503327 251243011 Rescheduling interrupts
CAL: 28611982 23099378 27059939 27241692 Function call interrupts
TLB: 21095731 21499698 21423392 21840338 TLB shootdowns
TRM: 0 0 0 0 Thermal event interrupts
THR: 0 0 0 0 Threshold APIC interrupts
MCE: 0 0 0 0 Machine check exceptions
MCP: 56307 56307 56307 56307 Machine check polls
HYP: 0 0 0 0 Hypervisor callback interrupts
ERR: 0
MIS: 0
软中断
$ cat /proc/softirqs
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 374358617 365669403 333492729 342436068
NET_TX: 238 293 226 282
NET_RX: 374868334 437870542 407556042 370615323
BLOCK: 2088818 2034795 2494437 3148050
BLOCK_IOPOLL: 0 0 0 0
TASKLET: 109 116 76 76
SCHED: 170334588 163435631 143882972 151212485
HRTIMER: 1043552 896154 596392 656918
RCU: 419294482 417240043 394297207 405259168
IRQ的CPU绑定
/proc/irq/{number}/smp_affinity
一般对硬盘和网卡做irq绑定
网卡irq号: cat /proc/interrupts | grep eth[0-9]- | awk '{print $1}'
$ cat /proc/irq/10/smp_affinity
f #1111
###如果有8个cpu,每个cpu的数值,每个cpu都绑定就是16进制FF
### 1 2 4 8
Binary Hex
CPU0 0000 0001 1
CPU1 0000 0010 2
CPU2 0000 0100 4
CPU3 0000 1000 8
CPU4 0001 0000 10
CPU5 0010 0000 20
CPU6 0100 0000 40
CPU7 1000 0000 80
修改
# 直接修改
echo '5' > /proc/irq/10/smp_affinity
# 推荐以下方式,例如24个cpu可以这样改
printf %x $((2**24-1)) | sudo tee /proc/irq/283/smp_affinity