Linux 中断相关节点
/proc/interrupts
cat 这个节点,会打印系统中所有的中断信息,如果是多核CPU,每个核都会打印出来。
包括每个中断的名字、中断号 IRQ number、每个中断的触发次数、在哪个CPU核处理的、是边沿触发还是电平触发,属于哪个中断控制器,都会打印出来。
/proc/irq/…
进入这个目录。会看到以中断号命名的文件夹,每个中断号文件夹下面都有几个节点,存储了这个中断的信息,比如smp_affinity、affinity_hint、spurious等。smp_affinity代表中断号核CPU之间的亲缘绑定关系,也就是如果某个中断号绑定了一个CPU核,那么这个中断就会一直在这个CPU上处理。
如何让某个中断在某个特定的 CPU 处理?
kernel 2.4 以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为 SMP IRQ Affinity.更多介绍请参看 Linux 内核源代码自带的文档:linux-4.14/Documentation/IRQ-affinity.txt
/proc/irq/{IRQ}/smp_affinity
/proc/irq/{IRQ}/smp_affinity_list
/proc/irq/{IRQ}/smp_affinity 指定给定的 irq中断号源允许哪些CPU执行,它是一个掩码位,比如是ff,代表11111111,表示这个中夺冠可以在 8 个 CPU 执行,具体在哪一个 CPU执行,靠分配器分配。
如果这个 /proc/irq/{IRQ}/smp_affinity 指定为00000001,代表这个IRQ只能在最后一个CPU核进行处理,其他CPU不允许处理,大家可以测试一下,主测试是 OK的(GIC支持,其他中断控制器不一定)。
串口手动赋值的重启以后会消失,可以在代码中调用 irq_set_affinity 函数,指定中断的掩码,来达到某个中断被固定CPU处理的需求。
中断分发机制
对于 GIC-V2 而言,SPI 的分发是根据 Distributor 中的 Interrupt Processor Targets Registers 来决定的。对于任何一个 SPI,其都有在某个 GICD_ITARGETSRn 寄存器中有 8 个bit标识送达的processor,如果只有一个 bit 被 set,那么就很简单了,如果该中断是当前优先级最高的中断,那么 Distributor 就会送到对应的 CPU interface,该中断最终会送达指定的 CPU。
如果该中断对应的 Interrupt Processor Targets Registers 中的那 8 个 bit 有多个 bit 被 set
的话,Distributor 如何处理呢?“依次轮着把产生的中断给各个CPU,还是说看哪个CPU有空就给哪个CPU来着”,让硬件处理这么复杂的逻辑有些不合适,实际上,GIC的硬件是不会进行任何判断的,也不会集成任何的算法,它就是根据Interrupt Processor Targets Registers的bit设定情况,忠实的把中断送往指定的一个processor或者多个processors。
大家可以去看看 gic_set_affinity 这个函数,这个函数确保一个中断的 Interrupt Processor Targets
Registers 中的那8个bit只有一个bit被设定。
/kernel5.15/drivers/irqchip/irq-gic-v3.c
在 1244 和 1246 行,1246 行就是在 online 的 CPU 中选中一个,1263 行写入到寄存器中,GIC 会读取这个寄存器,是哪个 CPU,然后将中断发给这个CPU。中间的函数很简单,大家可以自己看。
全部0条评论
快来发表一下你的评论吧 !