Linux绑定硬件IRQ到指定CPU核

在现在的多核处理器里,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:    1816637        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    5715256         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:         71         47         45         48         59         44         42         44   Non-maskable interrupts
LOC:    3203291    1967815    2437981    2304313    1093105     729632     722436     723293   Local timer interrupts
SPU:          0          0          0          0          0          0          0          0   Spurious interrupts
PMI:         71         47         45         48         59         44         42         44   Performance monitoring interrupts
IWI:     155671      55220      27492      59670      43244      30172      18019      38303   IRQ work interrupts
RTR:          0          0          0          0          0          0          0          0   APIC ICR read retries
RES:     395829     521236     466865     433429     286700     257603     256387     265018  Rescheduling interrupts
CAL: 4294967203        153        183        200        240        253        261        259   Function call interrupts
TLB:      50316      48055      49033      48274      31249      34265      33655      35763   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:       1944       1944       1944       1944       1944       1944       1944       1944   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这两个核心上处理。

评论

此博客中的热门博文

I/O映射之I/O端口

通过Netlink检测网线插拔

使用seq_file