首先是内核中断的分类,这里只是根据proc/interrupts下显示的中断进行分类,主要包含外部中断和IPI中断
cat proc/interrupts CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 1: 107049 104452 77919 106593 17651 2993 2558 3417 GICv3 59 Level r4p0_bcevt_timer 2: 340336 310429 188422 253369 39242 16601 7743 12236 GICv3 30 Edge arch_timer 3: 0 0 0 0 0 0 0 0 GICv3 26 Edge arch_timer 5: 1 0 0 0 0 0 0 0 GICv3 35 Level sprd_serial1 6: 18 0 0 0 0 0 0 0 GICv3 43 Level 70500000.i2c 7: 54 0 0 0 0 0 0 0 GICv3 44 Level 70600000.i2c 8: 8175 0 0 0 0 0 0 0 GICv3 46 Level 70800000.i2c 9: 309 0 0 0 0 0 0 0 GICv3 47 Level 70900000.i2c 11: 0 0 0 0 0 0 0 0 GICv3 82 Level sprd_dma 12: 60761 0 0 0 0 0 0 0 GICv3 92 Level mmc0 13: 0 0 0 0 0 0 0 0 GICv3 89 Level mmc1 14: 5 0 0 0 0 0 0 0 GICv3 90 Level mmc2 15: 2608 0 0 0 0 0 0 0 GICv3 87 Level musb-hdrc.0.auto 17: 0 0 0 0 0 0 0 0 GICv3 52 Edge sprd_codec_dp 21: 21688 0 0 0 0 0 0 0 GICv3 153 Level sprd_cpufreqhw 23: 25726 0 0 0 0 0 0 0 GICv3 78 Level DISPC 24: 3114 0 0 0 0 0 0 0 GICv3 83 Level GSP0 25: 0 0 0 0 0 0 0 0 GICv3 75 Level VSP 26: 0 0 0 0 0 0 0 0 GICv3 74 Level JPG 27: 0 0 0 0 0 0 0 0 GICv3 80 Level DSI_INT0 28: 0 0 0 0 0 0 0 0 GICv3 81 Level DSI_INT1 41: 15711 0 0 0 0 0 0 0 GICv3 71 Level pvrsrvkm 43: 0 0 0 0 0 0 0 0 GICv3 93 Level pub0_dmc_mpu 53: 0 0 0 0 0 0 0 0 GICv3 100 Level sprd-mailbox_source 54: 20246 0 0 0 0 0 0 0 GICv3 101 Level sprd-mailbox_target 55: 0 0 0 0 0 0 0 0 GICv3 151 Level sprd-mailbox_target 56: 0 0 0 0 0 0 0 0 GICv3 115 Edge cptl 57: 18 0 0 0 0 0 0 0 GICv3 70 Level spi5.0 58: 1 0 7 0 0 0 0 0 spi5.0 7 Edge chg_timer 59: 0 0 0 0 0 0 0 0 spi5.0 1 Edge sprd_rtc 60: 1 0 6 0 0 0 0 0 spi5.0 4 Edge 41800000.spi:pmic@0:gpio-controller@280 61: 1 0 2 0 0 0 0 0 spi5.0 10 Edge typec 62: 0 0 0 0 0 0 0 0 spi5.0 6 Edge sprd_codec_ap 63: 0 0 0 0 0 0 0 0 spi5.0 3 Edge sprdfgu 64: 0 0 0 0 0 0 0 0 GICv3 124 Level aon-busmonitor 65: 0 0 0 0 0 0 0 0 GICv3 119 Level apcpu-busmonitor 66: 1 0 2 0 0 0 0 0 irq-pmic-eic 0 Level musb vbus dectect irq 68: 1 0 0 0 0 0 0 0 irq-ap-eic 9 Edge 20300000.sdio cd 69: 164020 149945 117589 145551 20421 4260 3483 6879 CustomIPI 13 Edge trusty 70: 0 0 0 0 0 0 0 0 SPRDSensor-dev1 Edge SPRDSensor_consumer1 72: 0 0 0 0 0 0 0 0 irq-ap-gpio 124 Level Volume Down Key 73: 0 0 0 0 0 0 0 0 irq-pmic-eic 10 Level Volume Up Key 74: 0 0 4 0 0 0 0 0 irq-pmic-eic 1 Level Power Key 75: 2038 0 0 0 0 0 0 0 irq-ap-gpio 144 Edge adaptive_ts-irq 77: 0 0 0 0 0 0 0 0 irq-pmic-eic 9 Level sprdbat_vbat_detect 81: 0 0 0 0 0 0 0 0 irq-pmic-eic 13 Level headset_detect 82: 0 0 0 0 0 0 0 0 irq-pmic-eic 3 Level headset_button IPI0: 168450 167000 146626 128236 24290 12465 6847 9956 Rescheduling interrupts IPI1: 823 883 1115 1182 1209 1255 1223 1255 Function call interrupts IPI2: 0 0 0 0 0 0 0 0 CPU stop interrupts IPI3: 2433 2672 2316 3222 909 212 215 240 Timer broadcast interrupts IPI4: 9026 7987 2190 2279 1660 1189 128 179 IRQ work interrupts IPI5: 0 0 0 0 0 0 0 0 CPU wake-up interrupts Err: 38
外部中断
其中前面带编号的是外部中断,外部中断
网络数据包到达后,网卡向IOAPIC发起中断请求,IOAPIC查“中断重定向表”(Interrupt Redirection Table), 根据这个表的信息和数据包的信息,确定目标CPU,IOAPIC再把这个中断请求转发给目标CPU的LAPIC。目标CPU通过LAPIC收到数据包到达的中断请求,根据中断向量找到中断处理函数,处理中断请求。
IPI中断
下面的ID号是IPI开头的实际上是IPI中断,也可以叫做核间中断
IPI中断则比较简单:
在SMP系统中,每个cpu都有一个LAPIC,LAPC有两个重要的控制器 APIC_ICR 和 APIC_ICR2
APIC_ICR: 存储的是中断向量
APIC_ICR2:存储的是发送中断请求的目标
当CPU0 要给CPU1发送IPI中断时,CPU0只要把中断向量写入APIC_ICR,把中断请求目标写入APIC_ICR2,然后中断控制器就可以通过总线把中断请求发给CPU1的LAPIC。这样CPU1通过LAPIC就可以收到中断请求,并查中断向量表,找到中断处理函数,处理中断请求。
区别
在SMP系统中,每个cpu都有一个LAPIC,LAPC有两个重要的控制器 APIC_ICR 和 APIC_ICR2
APIC_ICR: 存储的是中断向量
APIC_ICR2:存储的是发送中断请求的目标
当CPU0 要给CPU1发送IPI中断时,CPU0只要把中断向量写入APIC_ICR,把中断请求目标写入APIC_ICR2,然后中断控制器就可以通过总线把中断请求发给CPU1的LAPIC。这样CPU1通过LAPIC就可以收到中断请求,并查中断向量表,找到中断处理函数,处理中断请求。
统计一段时间内的中断数的程序如下:
难点主要在数据是动态显示的,所以需要做动态处理:
https://github.com/feifeiyuan/features/blob/master/C/%E7%BB%9F%E8%AE%A1%E4%B8%80%E6%AE%B5%E6%97%B6%E9%97%B4%E7%9A%84%E4%B8%AD%E6%96%AD%E4%BF%A1%E6%81%AF/interrupts.c