![为什么本地CPU必须启用中断,否则内核抢占不执行?](https://linux22.com/image/8899/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%9C%AC%E5%9C%B0CPU%E5%BF%85%E9%A1%BB%E5%90%AF%E7%94%A8%E4%B8%AD%E6%96%AD%EF%BC%8C%E5%90%A6%E5%88%99%E5%86%85%E6%A0%B8%E6%8A%A2%E5%8D%A0%E4%B8%8D%E6%89%A7%E8%A1%8C%EF%BC%9F.png)
我读了《理解Linux内核》这本书。我无法理解一句话,那就是本地CPU必须启用本地中断,否则不执行内核抢占。这句话的意思是什么?
答案1
书上的这句话是错误的。禁用 IRQ 后,抢占仍然可能发生。有点。
抢占很棘手,因为它可以通过多种方式触发,其中只有一种是通过中断。例如,您始终可以通过调用 Schedule() 直接抢占代码,它不关心抢占启用/禁用或中断。 cond_resched() 是另一个不关心中断被禁用的函数。
所以问题的答案
为什么本地CPU必须启用中断,否则内核抢占不执行?
事实并非如此。在禁用中断的情况下,抢占仍然可能发生。任何时候都可能发生的异步抢占在禁用中断的情况下不会发生。但是由您正在执行的代码连续引起的抢占仍然可能发生。存在关于此的警告在文档中。
然而,如果中断被禁用,其中一些同步代码路径(例如通过 preempt_enable())将拒绝抢占,这无助于解决混乱。其他路径(如 cond_resched())仍然允许。原因很可能是因为该函数的明确性。 cond_resched() 是显式抢占请求,类似于schedule()。像 preempt_enable() 这样的东西不太明确,并且可能会意外触发抢占,因此如果禁用中断,它会阻止抢占。
答案2
如果禁止本地(上下文暗示“在此 CPU 上”)中断,则(本地)CPU 将永远不会看到中断来触发可能的内核抢占。