Linux kernel idle loop

2019-07-20 07:15发布

Inside the linux kernel idle loop, for quite a few architectures (SH, ARM, X86 etc.. afaik) are the following lines:

if(cpuidle_idle_call())
    pm_idle();

My doubt:

At-least for ARM, The default pm_idle function consists of WFI (Wait for interrupt) instruction but the confusing part is, interrupts are disabled then and are enabled after the WFI instruction executes, How does a CPU get back online from WFI when interrupts were disabled ?

I tried searching for my answers in various versions of linux, but the related code is unchanged since 2.6.32 (the last version i referred to) so it's more likely that I am missing something.

2条回答
Luminary・发光体
2楼-- · 2019-07-20 08:18

WFI wakes even if interrupts are disabled, but the ARM core doesn't receive the interrupts until interrupts are enabled again.

查看更多
萌系小妹纸
3楼-- · 2019-07-20 08:18

There are a couple of reasons for cpuidle_idle_call() to return an "error".

  1. There is no cpuidle driver installed for the CPU.
  2. cpuidle was disabled
  3. The driver could not be initialized

The missing driver is the most likely thing to happen. But in this case the kernel still has to burn cycles somehow. So it calls pm_idle, which on arm by default maps to default_idle. There the kernel checks if the cpu has a arm_pm_idle registered, which can be thought of like a lightweight cpuidle driver. If all fails it will fallback to cpu_idle, which HAS to be implemented and most of the time drains the write buffer and goes into WFI-mode.

There is a lot of redundancy in that whole thing, but that allows the developers to write simple idle-drivers and make them into full grown cpuidle drivers later if necessary.

The thing is that different SoCs provide different capabilities. For example, on kirkwood the idle-driver will set the DDR into Self refresh mode before switching to wfi-mode to safe some power. In theory it could also be extended to switch the cpu to a slower clock.

For your other question. Disabling interrupts will only prevent the cpu to trigger the interrupt-handler, it still needs to register that the interrupt occurred, otherwise you might loose data. So the handlers get disabled, but an incoming interrupt will still trigger the wakeup functionality of WFI.

查看更多
登录 后发表回答