The ARM SMP systems support two types of interrupts. SPI (shared peripheral interrupt) and PPI (peripheral private interrupts). The PPI is a per-CPU interrupt source. A special case for SMP of the PPI is an SGI (software generated interrupt); this is a CPU-to-CPU interrupt that is used to signal from one CPU to another in the SMP world (called IPI).Note1
A PPI定时器可用于允许每个 CPU 使用“无滴答调度”;也就是说,定时器中断是通过对未来时间事件的了解来安排的(谷歌计时轮,看看NO_HZ文档, ETC)。当前的Linux内核不使用这个特定的PPI定时器来进行调度。它仅用作延迟循环时间源。相反,全局 PPI 定时器用来。该定时器可以选择性地中断每个CPU,但寄存器组对于所有CPU来说是全局的。一个特定的CPU可以为自己安排一个中断;时基是全球性的。
复杂之处在于,任务必须从一个 CPU 迁移到另一个 CPU 才能平衡 CPU 之间的工作。此外,Linux 内核的核心代码/调度程序是为多个 CPU(或架构)编写的,它们可能没有这些per-CPU中断源。明确的答案可能取决于您的内核版本和使用的调度程序(或更一般的内核配置)。一般来说,繁忙的 CPU 会执行以下操作移民,其他 CPU 可能会在计时器滴答时唤醒,只是为了查看其中的任务是否应该运行(可能是迁移的进程)。如果NO_HZ
生效后,某些 CPU 可能根本无法唤醒;如果发生迁移,他们将获得 IPI。
无论如何,没有什么是ARM除了时钟源之外,还具体体现在CPU调度中。这是可能的ARMSMP系统没有一个全局PPI定时器。在这种情况下,每个 CPU 都可能会唤醒以服务中断,但大多数 CPU 可能会立即休眠。由于糟糕的定时器/中断控制器设计或糟糕的系统配置,这种情况可能发生在任何系统上。然而,即使在这些情况下,除非需要,否则代码也不会调用调度程序。
See: SMP 上的 Linux 调度程序(这可能是重复的,尽管在我看来答案不是很好),IBM 的完全公平调度程序文章和O'Reillys Linux 内核调度程序章节。
Note1:这实际上是GIC (or 通用中断控制器)术语。然而,大多数 ARM SMP 系统都使用这种中断控制器。它与 Cortex-A CPU 捆绑在一起,并作为某些 ARMv6 系统的外部软件组件。 ARM SMP 系统可以使用其他控制器,但这种情况可能极其罕见或根本不存在。
Edit:有两个ARM片上定时器;与 SOC 供应商计时器相比,这些计时器很有用,因为每个 Cortex-A 都有它们。其中之一用于代替“计数循环”来实现延迟。这在中断的情况下效果更好。我认为理解 SMP 调度并不重要,您可以忽略该注释,只知道该源文件不用于调度。这是我第一个看到的。如果您发现它确实分散了您的注意力,我将删除该信息。
See 这张纸 on 正时轮;它是关于“IP”/网络,但是概念NO_HZ
很相似。 IE。不要每 10 毫秒中断一次,只是为了增加刻度。在里面NO_HZ
在这种情况下,每个 CPU 都可以根据驱动程序和子系统发出的请求类型来设置未来的唤醒时间。 IE,schedule_work()
需要在 175ms 内运行,然后将计时器设置为 CPU 的该值,并且我们不会唤醒 17 次(如果系统节拍为 10mS),而只是将节拍增加 17 次。某些 CPU 可能需要超时驱逐当前进程以运行另一个进程以进行多任务处理,因此调度程序本身可以设置一个计时器。