前段时间由于项目需要,增加了can模块,视频模块等,结果在实际板子上运行的时候有时系统会突然死掉,通过网口也连接不到板子上,使用top查看系统负荷,发现系统的中断进程CPU占用率到达了100%。
最初考虑是哪个模块设计不合理导致的,但是单独运行每一个模块都没有问题,所有模块一起运行的时候就会出现高负荷的情况。
由于ksoftirqd/0是系统处理中断的进程,所以考虑是整个系统的中断过多导致的,并不是某一个模块的原因,是一个综合的结果。于是考虑从中断查起。
首先,查看系统的中断情况,查看文件/proc/interrupts ,可以看到从启动启动开始所有的中断记录,
cat /proc/interrupts
执行后结果如下:
CPU0 CPU1 CPU2 CPU3
0: 9 0 0 0 IO-APIC 2-edge timer
1: 398 18153 51880 102692 IO-APIC 1-edge i8042
8: 0 1 0 0 IO-APIC 8-edge rtc0
9: 4558 33953 4336 19231 IO-APIC 9-fasteoi acpi
12: 36882 889130 890172 1810837 IO-APIC 12-edge i8042
120: 0 0 0 0 PCI-MSI 16384-edge PCIe PME
第一列是中断号,后面几列是中断发生的CPU,最后是产生中断的设备。
上面查看CPU负荷是看到的ksoftirqd/0,说明是CPU0上处理中断的进程负荷过高。
于是查看CPU0列,会发现新增加的几个模块的中断都由CPU0处理。当某个时间中断过多时,CPU0的就被占满。
修改的策略是,将中断的负载均衡到各个CPU上。
中断号就是前面第一列的值,找到该中断的文件目录,修改smp_affinity,即可将中断指定到特定的CPU上。
均衡终端负载:将中断290设置在CPU2上
echo 2 > /proc/irq/290/smp_affinity
1,2,4,8,,f,分别表示CPU0, CPU1, CPU2,CPU3,或者全部CPU