参考博客与资料
FreeRTOS系列(1):基础知识——中断嵌套_猪哥-嵌入式的博客-CSDN博客_中断嵌套
Linux中断管理 (1)Linux中断管理机制 - ArnoldLu - 博客园
Linux支持中断嵌套吗?_denglin12315的博客-CSDN博客_linux中断嵌套
linux kernel的中断子系统之(三):IRQ number和中断描述符
1. 什么是中断嵌套
中断嵌套指中断系统正在执行一个中断服务L时,有另一个优先级更高的中断H触发,这时中断系统会暂时中止当前正在执行低优先级中断服务程序L,而去处理高级别中断H,待处理完毕,再返回被中断了的中断服务程序L继续执行。中断嵌套的具体图示请参考FreeRTOS系列(1):基础知识——中断嵌套_猪哥-嵌入式的博客-CSDN博客_中断嵌套
2. 中断抢占与中断嵌套的关系
先来看看ARM-GIC中断处理的粗略时序<ARM Generic Interrupt Controller V2.0-3.2>
- GIC会将pending状态优先级最高的中断请求发送给CPU
- CPU读取GICC_IAR寄存器来ack该中断请求并处理该中断
- CPU处理完中断后,CPU写GICC_EOIR寄存器告诉GIC中断处理完成
中断抢占<ARM Generic Interrupt Controller V2.0-3.3.1>
所以说按照文字描述,中断嵌套的实质就是中断抢占机制,GIC将符合条件的高优先级中断上报到CPU,进而CPU响应高优先级中断暂停处理低优先级中断。
疑惑: 未能理解Starting to service an interrupt while another interrupt is still active is sometimes described as interrupt nesting 这句话,interrupt nesting不就是中断嵌套?
参考Linux中断管理 (1)Linux中断管理机制 - ArnoldLu - 博客园
站在GIC的角度: GIC能够在低优先级中断处理完毕之前将高优先级中断送至CPU
站在Linux的角度: Linux hard irq处理CPU全程关中断,所以即使GIC上报了高优先级中断,CPU也置之不理,需要等待低优先级中断处理完毕,再去响应上报的高优先级中断,即:
所以Linux下:
- 高优先级中断无法抢占正在执行的低优先级中断。
- 同处于pending状态的中断,优先响应高优先级中断进行处理
参考时序图如下:
3. 为什么Linux不支持中断嵌套
准确的答案应该这么讲: 历史上Linux是支持中断嵌套的,但是现在不支持了
历史上,linux中断处理有快慢中断和IRQF_DISABLED这个标记的概念,如果中断处理函数没有带IRQF_DISABLED这个标记,linux内核代码在处理中断时会打开本CPU响应中断的能力,而GIC又有能力上报优先级更高的中断到CPU,所以这时ARM+GIC组合的系统就能支持中断抢占嵌套
在后来的一个commit中,中断处理中不再支持打开CPU中断的操作,从而不再支持中断嵌套
kernel/git/torvalds/linux.git - Linux kernel source tree
4. 总结
THEN(支持中断嵌套) | NOW(不支持中断嵌套) | |
GIC | 支持中断抢占 | 支持中断抢占 |
CPU | IRQ mode关中断 | IRQ mode关中断 |
Linux内核 | IRQF_DISABLED开CPU中断 | N/A |
风险 | 栈溢出 |