为什么在重置中断关联性时会调用 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 芯片上路由的事务可能会与发送中断的事务竞争 - 并且可能需要一些周期才能到达,因此您最终可能会得到:
- 告诉 APIC 将中断发送给其他人 CPU,而不是我。
- 中断!
所以代码的作用基本上是:
- 告诉 APIC 将中断发送给其他人 CPU 而不是我。
- 等待 bit.Enough 以确保中断重新路由完成。 (如何知道有多少时间足以等待?也许它记录在 APIC 规范中,也许它的内部知识是一些英特尔 VLSI 工程师透露给他们 Linux 的人 - 我不知道 :-)
- 通过读取发送中断时锁定的 APIC 上的寄存器来检查是否发生中断,如果发现任何中断,将其作为 IPI 发送到正确的目标。
- 现在我们知道没有中断会真正影响到我们。
我正在尝试更改导致 cpu 失效的代码,结果遇到了一些我不完全理解的问题:
从 cpu_online_mask 中移除核心后发生的事情之一是重置中断关联。 这是在 /arch/x86/kernel/irq.c 中的 fixup_irqs() 函数中完成的。 该函数重置中断亲缘关系,然后调用 mdelay(1)(仅等待 1 毫秒),最后转向处理可能的 "lost" 个中断。
我的问题是:为什么必须调用 mdelay(1)?没有它会发生什么? 我的猜测是 APIC 中的重新路由需要时间才能生效...但我确信对此有更令人信服的解释。
谢谢!
简而言之 shell,fixup_irq() 中存在竞争条件 - 该函数首先遍历路由到正在脱机的 CPU 的所有 IRQ,并且告诉硬件将它们路由到其他地方。
问题是,更改此中断路由的过程不是原子的或瞬时的。更改 PIC 芯片上路由的事务可能会与发送中断的事务竞争 - 并且可能需要一些周期才能到达,因此您最终可能会得到:
- 告诉 APIC 将中断发送给其他人 CPU,而不是我。
- 中断!
所以代码的作用基本上是:
- 告诉 APIC 将中断发送给其他人 CPU 而不是我。
- 等待 bit.Enough 以确保中断重新路由完成。 (如何知道有多少时间足以等待?也许它记录在 APIC 规范中,也许它的内部知识是一些英特尔 VLSI 工程师透露给他们 Linux 的人 - 我不知道 :-)
- 通过读取发送中断时锁定的 APIC 上的寄存器来检查是否发生中断,如果发现任何中断,将其作为 IPI 发送到正确的目标。
- 现在我们知道没有中断会真正影响到我们。