SMP调度如何在Linux内核中运行?(ARM架构)

use*_*363 5 arm scheduler linux-kernel

在linux中,调度程序将在经过特定时间后触发.据我所知,定时器触发一个中断,进而触发一次调用schedule.

在SMP系统中,我在"理解Linux内核"一书中读到"每个处理器自己运行调度程序()函数".这是否意味着每个定时器中断都会触发每个cpu同时进行重新调度?

art*_*ise 16

ARM SMP系统支持两种类型的中断.SPI(共享外设中断)和PPI(外设专用中断).PPI是每CPU中断源.PPI的SMP的一个特例是SGI(软件生成的中断); 这是一个CPU到CPU的中断,用于在SMP世界中从一个CPU发送信号到另一个CPU(称为IPI).注1

PPI计时器可被用于允许每个CPU使用"无空循环调度"; 计时器中断是通过未来时间事件的知识(谷歌计时轮,查看NO_HZ文档等)安排的.当前的Linux内核不使用此特定的PPI计时器进行调度.它仅用作延迟循环时间源.而是使用全局PPI计时器.该定时器可以有选择地中断每个CPU,但寄存器组对所有CPU都是全局的.特定的CPU可以为自己安排中断; 时间基础是全球性的.

复杂的是必须将任务从一个CPU迁移到另一个CPU,以便在CPU之间平衡工作.此外,Linux内核的核心代码/调度程序是为多个CPU(或体系结构)编写的,它们可能没有这些每CPU中断源.明确的答案可能取决于您的内核版本和使用的调度程序(或更常见的内核配置).通常,忙碌的CPU将执行迁移,其他CPU可能会在计时器滴答时唤醒,以查看其中的任务是否应该运行(可能是迁移的进程).如果NO_HZ有效,某些CPU可能根本不会唤醒; 他们将在迁移的情况下获得IPI.

在任何情况下,除了时钟源之外,CPU调度中没有任何特定于ARM的内容.对于有可能ARM SMP系统,没有一个全球PPI计时器.在这种情况下,每个CPU可能会唤醒以服务中断,但大多数可能会立即休眠.由于定时器/中断控制器设计错误或系统配置错误,这可能发生在任何系统上.但是,即使在这些情况下,除非需要,否则代码不会调用调度程序.

请参阅:SMP上的Linux调度程序(虽然答案不是很好,但可能是重复的IMO),IBM完全公平的调度文章和O'Reillys Linux内核调度程序章节.

注1: 这实际上是GIC(或通用中断控制器)术语.但是,大多数ARM SMP系统都使用此中断控制器.它与Cortex-A CPU捆绑在一起,作为一些ARMv6系统的外部软组件.ARM SMP系统可能使用另一个控制器,但它可能非常罕见或不存在.

编辑:有两个ARM片上定时器; 这些都很有用,因为与SOC供应商定时器相比,每个Cortex-A都有它们.其中一个用于代替"计数循环"延迟.这在中断的情况下效果更好.我认为理解SMP调度并不重要,您可以忽略该注释,只知道该源文件不用于调度.这是我看到的第一个.如果你发现它真的让人分心,我会删除这些信息.

参见本文关于定时轮 ; 它是关于'IP'/网络,但概念NO_HZ是类似的.IE浏览器.不要每10mS中断一次,只是为了增加刻度.在这种NO_HZ情况下,每个CPU可以根据驱动程序和子系统给出的请求类型设置未来的唤醒时间.即,schedule_work()需要在175ms运行,然后将计时器设置为CPU的值,并且我们不会唤醒17次(如果系统标记为10mS),而只是增加17的滴答.某些CPU可能需要超时驱逐当前进程以运行另一个进程以进行多任务处理,因此调度程序本身可以设置计时器.