中断上下文的锁
这是内核编程的第一铁律。
规则
在中断处理程序 (ISR) 中,绝对不能 Sleep,绝对不能持有可能会 Sleep 的锁。
为什么?
中断不仅打断了当前进程,它甚至不属于任何进程的上下文。
- 如果你在 ISR 里
sleep,你要切换到哪个进程?ISR 没有struct proc供调度器保存状态。 - 死锁场景 (Deadlock):
- 进程 A 持有
uart_lock正在写数据。 - 突然发生 UART 中断,CPU 跳到
uartintr。 uartintr试图获取uart_lock。- 死局:
uartintr在等 A 释放锁,但 A 被uartintr抢占了,只有等uartintr结束 A 才能继续运行释放锁。 - 结果: 自旋锁死循环,CPU 挂起。
- 进程 A 持有
解决方案
Off-Interrupts: 如果一个锁(如 uart_lock)既在中断里用,又在进程里用。那么进程在获取该锁之前,必须关闭中断 (push_off),释放锁之后再打开。