为什么在重置中断关联性时会调用 mdelay(1)?

Why is there a call to mdelay(1) when resetting interrupt affinities?

我正在尝试更改导致 cpu 失效的代码,结果遇到了一些我不完全理解的问题:

从 cpu_online_mask 中移除核心后发生的事情之一是重置中断关联。 这是在 /arch/x86/kernel/irq.c 中的 fixup_irqs() 函数中完成的。 该函数重置中断亲缘关系,然后调用 mdelay(1)(仅等待 1 毫秒),最后转向处理可能的 "lost" 个中断。

我的问题是:为什么必须调用 mdelay(1)?没有它会发生什么? 我的猜测是 APIC 中的重新路由需要时间才能生效...但我确信对此有更令人信服的解释。

谢谢!

简而言之 shell,fixup_irq() 中存在竞争条件 - 该函数首先遍历路由到正在脱机的 CPU 的所有 IRQ,并且告诉硬件将它们路由到其他地方。

问题是,更改此中断路由的过程不是原子的或瞬时的。更改 PIC 芯片上路由的事务可能会与发送中断的事务竞争 - 并且可能需要一些周期才能到达,因此您最终可能会得到:

  1. 告诉 APIC 将中断发送给其他人 CPU,而不是我。
  2. 中断!

所以代码的作用基本上是:

  1. 告诉 APIC 将中断发送给其他人 CPU 而不是我。
  2. 等待 bit.Enough 以确保中断重新路由完成。 (如何知道有多少时间足以等待?也许它记录在 APIC 规范中,也许它的内部知识是一些英特尔 VLSI 工程师透露给他们 Linux 的人 - 我不知道 :-)
  3. 通过读取发送中断时锁定的 APIC 上的寄存器来检查是否发生中断,如果发现任何中断,将其作为 IPI 发送到正确的目标。
  4. 现在我们知道没有中断会真正影响到我们。