在现在的多核处理器里,Linux下默认是将硬件IRQ分配到所有的CPU核心上,会优先使用第0核(即CPU0),那么我们要如何手动指定到某个或某几个核心上呢?这涉及到SMP IRQ Affinity。首先,我们可以通过如下命令cat /proc/interrupts来获取当前IRQ对应CPU核心的情况,我的电脑有如下返回值:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
0: 17 0 0 0 0 0 0 0 IR-IO-APIC-edge timer
1: 2 0 0 0 0 0 0 0 IR-IO-APIC-edge i8042
7: 0 0 0 0 0 0 0 0 IR-IO-APIC-edge parport0
8: 0 0 0 0 0 1 0 0 IR-IO-APIC-edge rtc0
9: 0 0 0 0 0 0 0 0 IR-IO-APIC-fasteoi acpi
12: 3 0 0 0 0 0 1 0 IR-IO-APIC-edge i8042
16: 32 0 0 0 1 0 0 0 IR-IO-APIC-fasteoi ehci_hcd:usb1
19: 7272446 193 135 74 1130 157 106 278 IR-IO-APIC-fasteoi ata_piix, ata_piix
23: 32 0 0 0 1 0 0 0 IR-IO-APIC-fasteoi ehci_hcd:usb2
40: 0 0 0 0 0 0 0 0 DMAR_MSI-edge dmar0
41: 0 0 0 0 0 0 0 0 DMAR_MSI-edge dmar1
42: 0 0 0 0 0 0 0 0 IR-PCI-MSI-edge xhci_hcd
43: 614 9 1 1 18283973 19 10 12 IR-PCI-MSI-edge eth0
44: 3 127 0 0 18 154 2 51 IR-PCI-MSI-edge snd_hda_intel
45: 42 1 0 0 0 0 0 0 IR-PCI-MSI-edge i915
NMI: 1075 823 812 812 774 816 804 802 Non-maskable interrupts
LOC: 14225495 10987071 12518753 12499043 4462117 3599360 3668949 3712199 Local timer interrupts
SPU: 0 0 0 0 0 0 0 0 Spurious interrupts
PMI: 1075 823 812 812 774 816 804 802 Performance monitoring interrupts
IWI: 668959 243175 173864 217368 333949 236190 164444 203926 IRQ work interrupts
RTR: 0 0 0 0 0 0 0 0 APIC ICR read retries
RES: 4325328 5435860 4978567 5009075 4562785 4288325 4511659 4408518 Rescheduling interrupts
CAL: 1766 5366 1609 985 608 327 290 282 Function call interrupts
TLB: 615205 531403 532879 503306 486281 510158 501906 511339 TLB shootdowns
TRM: 0 0 0 0 0 0 0 0 Thermal event interrupts
THR: 0 0 0 0 0 0 0 0 Threshold APIC interrupts
MCE: 0 0 0 0 0 0 0 0 Machine check exceptions
MCP: 4841 4841 4841 4841 4841 4841 4841 4841 Machine check polls
ERR: 0
MIS: 0
假如我们想修改RTC对应的响应处理器核心,那么我们可以先通过命令cat /proc/irq/8/smp_affinity来获得如下返回值(其中8为RTC对应的中断号,在上面的返回值第一列可以看到):
ff
那么表示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
看出来了吧,将上面的值相加,就是16进制FF。
那么我们要设置IRQ到指定的CPU上面,可以使用如下命令:
echo "2" > /proc/irq/8/smp_affinity
上述命令将RTC的中断指定到CPU1核心上处理,也可以指定多个核心,如下:
echo "6" > /proc/irq/8/smp_affinity
将RTC中断指定到CPU1和CPU2这两个核心上处理。
网友评论