在内核代码中禁用同步中断



为什么在内核中同步代码时需要禁用中断?

例如,下面的代码取自linux的schedule()函数:

need_resched:
prev = current;
rq = this_rq();
**spin_lock_irq(&rq->lock);** //disables interrupts
switch (prev->state) {
case TASK_INTERRUPTIBLE:
    if (unlikely(signal_pending(prev))) {
        prev->state = TASK_RUNNING;
        break;
    }
default:
    deactivate_task(prev, rq);
case TASK_RUNNING:
    ;
}

spin_lock_irq()函数禁用中断,但为什么需要它?假设我没有禁用中断,而出现了中断,那么我就处理它,然后回到调度器并继续我正在做的事情。

这是必要的,因为调度程序可以通过软件和硬件中断进入。

软件中断,例如。Sleep()调用和线程间通信调用(例如信号量,condvar或事件信号)可能会改变正在运行的线程集,因此将请求调度程序运行。这些调用具有线程/进程上下文,并且在它们调用内核时发生。

硬件中断,例如。KB、鼠标、磁盘、网卡导致驱动程序运行,驱动程序很可能希望通过运行调度程序来改变正在运行的线程集,例如。使被阻塞等待磁盘读取的线程准备就绪。硬件中断没有线程/进程上下文,可以在中断启用时随时发生。

调度程序代码/数据的部分是不可重入的。如果没有暂时禁用这些段的中断,当调度器被硬件中断并从驱动程序重新进入时,将会出现混乱。

最新更新