我最近正在阅读Linux内核开发,我有一些与禁用抢占相关的问题。
在第7章的"中断控制"部分,它说:
Moreover, disabling interrupts also disables kernel preemption.
我还从书中读到,在以下情况下可能会发生内核抢占:
When an interrupt handler exits, before returning to kernel-space.
When kernel code becomes preemptible again.
If a task in the kernel explicitly calls schedule()
If a task in ther kernel blocks (which results in a call to schedule())
但我无法将禁用中断与这些情况联系起来。
据我所知,自旋锁将使用preempt_disable()函数禁用抢占。
帖子究竟什么是"自旋锁"?
说:
On a single core machine a spinlock is simply a"disable interrupts" or"raise IRQL" which prevents thread scheduling completely.
preempt_disable()是否通过禁用中断来禁用抢占?
我不是调度大师,但我想解释一下我是如何看待它的。
这里有几件事。
preempt_disable()不会禁用IRQ。它只增加一个thread_info->preempt_count变量。
禁用中断还会禁用抢占,因为调度程序在此之后不起作用 - 但仅限于单CPU计算机上。在SMP上它是不够的,因为当你关闭一个CPU上的中断时,另一个/其他人仍然异步地做/做某事。
Big Lock(意味着 - 关闭所有CPU上的所有中断)正在大大降低系统速度 - 所以这就是为什么它不再使用了。这也是preempt_disable()不关闭IRQ的原因。
你可以看到什么是preempt_disable()。试试这个:
1.获得一个旋锁。
2.通话时间表()
在dmesg中,您将看到类似"BUG:schedule while atomic"的内容。当调度程序检测到您的进程处于原子(非抢占)上下文但会自行调度时,会发生这种情况。
祝好运。
谢谢你的详细解答。 但我仍然不明白为什么在禁用单CPU机器上的中断后调度程序无法正常工作。
没有中断 - 没有时钟。 没有时钟 - 没有计时器。
如果我只禁用抢占(不禁用中断)并且同时中断发生在系统中,并且在禁用中断后会发生什么,会产生什么影响? 在这种情况下,"preempt_count"变量将更有效。 (研究手臂中断处理)
@Sebastian Mountaniol:"Big Lock(意味着 - 关闭所有CPU上的所有中断)"你能解释一下吗? 大锁实际上是一个锁,虽然是所有LWP的全球锁。 但它并不等于禁用中断。
在我编写的用于监视/分析任务的测试内核模块中,我尝试通过以下方式禁用中断:
1 - 使用local_irq_save()
2 - 使用spin_lock_irqsave()
3 - 手动disable_irq()到/ proc / interrupts中的所有IRQ
在所有3个案例中,我仍然可以使用hrtimer来测量时间,即使IRQ被禁用(我正在监视的任务也被抢占)。
我觉得这个怪人很奇怪......我个人期待Sebastian Mountaniol指出的 - >没有中断 - 没有时钟。没有时钟 - 没有计时器......
Linux内核2.6.32在单核,单CPU上......任何人都可以有更好的解释吗?
我认为一些Linux内核定时器使用上一个定时器中断技巧加上CPU周期定时器。 所以你得到准确的时间,直到循环计数器溢出。
啊......非常聪明的实施:)