GIC/NVIC中断并发场景下spin_lock_irqsave死锁可能性问询
中断自旋锁执行序列的死锁可能性分析
问题背景
多个ISR共享如下代码:
spin_lock_irqsave <critical section> spin_unlock_irqrestore
系统全程为可抢占中断模式,假设出现以下执行序列:
- 低优先级中断触发,GIC/NVIC跳转至对应ISR;
- 低优先级中断开始原子执行
spin_lock_irqsave; - 在该低优先级中断完成抢占与中断禁用前,高优先级中断触发,GIC/NVIC将其转发至软件;
- 低优先级中断完成
spin_lock_irqsave执行(原子操作),禁用抢占与中断并获取自旋锁; - 高优先级中断处于软件队列中,抢占低优先级中断并自旋等待自旋锁。
问题核心:上述执行序列是否可能发生?是否会导致高优先级中断自旋进而引发死锁?还是软件会阻止切换至高优先级中断,等待低优先级中断释放锁?
结论:该执行序列不可能发生,不会引发死锁
原因如下:
spin_lock_irqsave的原子性保障:spin_lock_irqsave是一个原子操作,从启动执行到完成锁获取、禁用本地中断及抢占的整个流程,完全不可被打断。步骤3中提到的“低优先级中断执行spin_lock_irqsave过程中被高优先级中断插入”的场景,根本不存在。- 硬件中断的阻断逻辑:当
spin_lock_irqsave执行完成时,当前CPU的中断已经被硬件级禁用(比如修改ARM架构的DAIF寄存器、x86的EFLAGS寄存器)。此时GIC/NVIC即便收到高优先级中断请求,也无法将其投递到当前CPU执行,直到spin_unlock_irqrestore恢复中断状态。 - 抢占机制的限制:即便系统是可抢占内核模式,
spin_lock_irqsave也会同步禁用抢占。这意味着低优先级ISR在持有自旋锁的临界区执行期间,当前CPU上的任何抢占(包括高优先级任务或中断)都无法触发。高优先级中断会被暂时挂起,直到低优先级ISR释放锁、恢复中断和抢占能力后,才会被调度执行。
简言之,spin_lock_irqsave的设计目标就是彻底隔离当前CPU的临界区,杜绝任何中断或抢占干扰,自然不会出现高优先级中断抢占持锁低优先级中断并自旋等待的死锁场景。
内容的提问来源于stack exchange,提问作者Ajay Garg
相关产品推荐
相关产品推荐

