CPU调度器实现提示:针对特定体系结构代码【ChatGPT】

发布时间 2023-12-11 20:05:25作者: 摩斯电码

《CPU调度器实现提示:针对特定体系结构代码》

Nick Piggin,2005

上下文切换

  1. 运行队列锁定 默认情况下,调用switch_to体系结构函数时会锁定运行队列。除非switch_to需要获取运行队列锁,否则通常不会出现问题。这通常是由上下文切换中的唤醒操作引起的。请参阅arch/ia64/include/asm/switch_to.h以获取示例。

要求调度器在运行队列未锁定的情况下调用switch_to,您必须在头文件中(通常是定义switch_to的文件)使用#define __ARCH_WANT_UNLOCKED_CTXSW。

在CONFIG_SMP情况下,无锁上下文切换对核心调度器实现只会引入非常小的性能损失。

CPU空闲

您的cpu_idle例程需要遵守以下规则:

  1. 抢占现在应该在空闲例程中禁用。只有在调用schedule()时才应启用,然后再次禁用。

  2. need_resched/TIF_NEED_RESCHED只会被设置,直到运行任务调用schedule()之前永远不会被清除。空闲线程只需要查询need_resched,可能永远不会设置或清除它。

  3. 当cpu_idle发现(need_resched() == 'true')时,应调用schedule()。否则不应调用schedule()。

  4. 检查need_resched时唯一需要禁用中断的情况是,如果我们将处理器置于休眠状态直到下一个中断(这不提供对need_resched的保护,而是防止丢失中断):

    4a. 这种类型的休眠常见问题似乎是:

    local_irq_disable();
    if (!need_resched()) {
    		local_irq_enable();
    		*** resched interrupt arrives here ***
    		__asm__("sleep until next interrupt");
    }
    
  5. TIF_POLLING_NRFLAG可以由不需要中断唤醒的空闲例程设置,当need_resched变为高时。换句话说,它们必须定期轮询need_resched,尽管可能合理地进行一些后台工作或进入低CPU优先级。

    5a. 如果设置了TIF_POLLING_NRFLAG,并且我们决定进入中断休眠,那么需要清除它,然后发出内存屏障(随后需要禁用中断进行need_resched的测试,如第3点所述)。

arch/x86/kernel/process.c中有轮询和休眠空闲函数的示例。

可能的体系结构问题

我发现的可能的体系结构问题(尝试修复或未修复):

ia64 - safe_halt调用与中断存在竞争条件吗?(它会休眠吗?)(见#4a)

sparc - 此时是否开启IRQ?将local_irq_save更改为_disable。

    TODO:需要辅助CPU来禁用抢占(见#1)