为什么禁止中断禁止内核抢占以及自旋locking如何禁用抢占

我正在最近阅读Linux Kernel Development ,并且有几个与禁用抢占有关的问题。

  1. 在第7章的“中断控制”一节中,它说:

    而且,禁止中断也会禁止内核抢占。

    我也从书中读到,在以下情况下可能发生内核抢占:

    当中断处理程序退出时,在返回到内核空间之前。
    当内核代码再次被抢占时。
    如果内核中的任务显式调用schedule()
    如果一个任务在内核块(导致调用schedule())

    但是我不能将禁用中断与这些情况联系起来。

  2. 据我所知,螺旋锁将禁用preempt_disable()函数的抢占。

    post什么是“自旋锁”? 说:

    在单核心机器上,自旋锁只是一个“禁用中断”或“引发IRQL”,它完全阻止了线程调度。

    preempt_disable()是否禁用中断来禁止抢占?

我不是一个调度大师,但是我想解释一下我是如何看待它的。 这里有几件事情。

  1. preempt_disable() 不会禁用IRQ 。 它只是增加一个thread_info->preempt_count变量。
  2. 禁用中断也会禁用抢占,因为之后的调度程序不工作 – 但只能在单CPU机器上运行。 在SMP上这是不够的,因为当你在一个CPU上关闭中断时,其他/另外一些CPU仍然/异步执行某些操作。
  3. 大锁(意味着关闭所有CPU上的所有中断)会大大减慢系统的速度 – 所以这就是为什么它不再被使用。 这也是为什么preempt_disable()不关闭IRQ的原因。

你可以看到什么是preempt_disable()。 试试这个:1.获得一个自旋锁。 2.通话计划()

在dmesg中,您将看到类似“BUG:调度原子”的内容。 当调度程序检测到您的进程在原子(而不是抢占)上下文中,但它调度自己时,会发生这种情况。

祝你好运。

在我编写的一个测试内核模块来监视/分析一个任务时,我试过通过以下方法禁止中断:

1 – 使用local_irq_save()

2 – 使用spin_lock_irqsave()

3 – 手动disable_irq()到/ proc / interrupts中的所有IRQ

在所有这三种情况下,即使禁用了IRQ,我仍然可以使用hrtimer来衡量时间(我监视的任务也被抢先了)。

我觉得这个veeeeerrrryyyy奇怪…我个人预测什么塞巴斯蒂安Mountaniol指出 – >没有中断 – 没有时钟。 没有时钟 – 没有计时器…

Linux内核2.6.32在单核心,单CPU …任何人都可以有一个更好的解释?