中断上下文的锁

这是内核编程的第一铁律。

规则

在中断处理程序 (ISR) 中,绝对不能 Sleep,绝对不能持有可能会 Sleep 的锁。

为什么?

中断不仅打断了当前进程,它甚至不属于任何进程的上下文。

  1. 如果你在 ISR 里 sleep,你要切换到哪个进程?ISR 没有 struct proc 供调度器保存状态。
  2. 死锁场景 (Deadlock):
    • 进程 A 持有 uart_lock 正在写数据。
    • 突然发生 UART 中断,CPU 跳到 uartintr
    • uartintr 试图获取 uart_lock
    • 死局: uartintr 在等 A 释放锁,但 A 被 uartintr 抢占了,只有等 uartintr 结束 A 才能继续运行释放锁。
    • 结果: 自旋锁死循环,CPU 挂起。

解决方案

Off-Interrupts: 如果一个锁(如 uart_lock)既在中断里用,又在进程里用。那么进程在获取该锁之前,必须关闭中断 (push_off),释放锁之后再打开。