Skip to main content
 首页 » 编程设计

linux-kernel之为什么在中断上下文中执行的内核代码/线程无法休眠

2024年05月22日48Leo_wl

我正在阅读 Robert Love 的以下文章

http://www.linuxjournal.com/article/6916

上面写着

“...让我们讨论一下工作队列在进程上下文中运行的事实。这与其他下半部机制形成对比,这些机制都在中断上下文中运行。在中断上下文中运行的代码无法休眠或阻塞,因为中断上下文没有可用于重新调度的后备进程。因此,由于中断处理程序不与进程关联,因此调度程序没有任何东西可以进入休眠状态,更重要的是,调度程序没有任何东西可以唤醒。 ..”

我不明白。 AFAIK,内核中的调度程序是O(1),即通过位图实现的。那么是什么阻止调度程序将中断上下文置于 sleep 状态并获取下一个可调度进程并将控制权传递给它呢?

请您参考如下方法:

So what stops the scehduler from putting interrupt context to sleep and taking next schedulable process and passing it the control?

问题是中断上下文不是一个进程,因此不能进入休眠状态。

当中断发生时,处理器将寄存器保存到堆栈上并跳转到中断服务程序的开头。这意味着当中断处理程序运行时,它在中断发生时正在执行的进程的上下文中运行。中断正在该进程的堆栈上执行,当中断处理程序完成时,该进程将恢复执行。

如果您尝试在中断处理程序中休眠或阻塞,您不仅会停止中断处理程序,还会停止它中断的进程。这可能很危险,因为中断处理程序无法知道被中断的进程正在做什么,或者即使挂起该进程是否安全。

可能出现问题的一个简单情况是中断处理程序与其中断的进程之间出现死锁。

  1. Process1进入内核模式。
  2. Process1 获取LockA
  3. 发生中断。
  4. ISR 开始使用 Process1 的堆栈执行。
  5. ISR 尝试获取LockA
  6. ISR 调用 sleep 来等待 LockA 被释放。

此时,你陷入了僵局。 Process1 在 ISR 处理完其堆栈之前无法恢复执行。但 ISR 被阻塞,等待 Process1 释放 LockA