查看中断分配
典型输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| CPU0 CPU1 CPU2 CPU3 29: 18801666 16647304 15917474 14185149 GIC arch_timer 30: 0 0 0 0 GIC arch_timer 32: 0 0 0 0 GIC timer0 51: 0 0 0 0 GIC mmc1 52: 0 0 0 0 GIC tegra-otg, tegra-udc 53: 0 0 0 0 GIC pmc_usb_phy_wake_isr 55: 0 0 0 0 GIC tegra-sata 63: 68639 0 0 0 GIC mmc0 69: 142835 265551 0 0 GIC serial-tegra.1
71: 3748708 0 0 0 GIC tegra-xhci:usb1
97: 9260863 0 0 0 GIC host_syncpt
122: 602 0 0 0 GIC serial
131: 483307 0 0 0 GIC PCIe-MSI
642: 477100 0 0 0 PCIe-MSI eth3 643: 6232 0 0 0 PCIe-MSI iwlwifi
|
其中 serial-tegra.1 对应 TK1 上 /dev/ttyTHS1 的中断。第一列代表的是中断号,每个 CPU 下面的数字代表接收到的中断数。
默认情况下,系统用 CPU0 去收所有的中断。处理中断是非常耗时的任务,而系统又认为所有 CPU 的计算能力是一致的。当 CPU0 用了 30% 的资源去处理中断时,那别的 CPU 也只能发挥 70% 的计算性能,所以需要合理分配中断。
Affinity 指的是任务与处理器的亲和度。如果我们一直用处理器 X 运行任务 Y,两者 affine。Affine 的情况下,处理器的 cache 里会存有任务部分的 memory,所以效率是比较高的。
和一般进程相反,对中断来说,affine 到某个处理器则会导致低效。因为中断程序往往非常小,将中断程序存在 CPU 里不能改善 cache hits,而多个中断会长期占用 CPU。调度器会认为所有核都和这个中断处理核一样忙,导致其它 CPU 实际上很空闲,但是缺用不上。
APIC (Advanced Programmable Interrupt Controller)
APIC 负责分配中断,默认将所有中断交给 CPU0 处理。APIC 具有好几种传输 (delivery) 及 (destination) 模式,包括:
- physical
- logical
- fixed
- low priority
能够将中断绑到任意核上 (其实只能绑到前八个核),还能做负载均衡。
使用
- 对某些系统来说,可能需要先停掉 irqbalance 服务
1
| # /etc/init.d/irqbalance stop
|
对每一个中断号, /proc/irq/ 下面都有一个对应的目录,下面有一个 smp_affinity 文件,通过修改这个文件,能够改变该中断绑定的核。
文件里存的是一个 16 进制的 bitmask。哪一位为 1,就用哪个核。
比如说我们要让 CPU1 处理 TK1 的串口中断,可以这样:
1
| sudo bash -c 'echo 2 > /proc/irq/69/smp_affinity'
|
理论上,f 能够使四个核平均处理中断。但是,实际结果还要看 APIC 是否处于 physical destination mode 及 low priority delivery mode,如果是的话才可以,可惜 TK1 不是。
- 在内核里关掉 CONFIG_HOTPLUG_CPU 可以使 APIC 正常工作
ubuntu 可以安装一个叫 irqbalance 的东西,说不定可以解决