COUPLED CPUIDLE STATES(9)
πΈ Coupled cpuidle states πΈ
okay bestie, this is Coupled cpuidle states(9) from the Kernel API Manual, and it is genuinely iconic kernel lore π
. Section 9, ARM power-management girlies, let's go π«Ά.
On some ARM SMP SoCs (OMAP4460, Tegra 2, and probably more), the cpus cannot be independently powered down, either due to sequencing restrictions (on Tegra 2, cpu 0 must be the last to power down), or due to HW bugs (on OMAP4460, a cpu powering up will corrupt the gic state unless the other cpu runs a work around). Each cpu has a power state that it can enter without coordinating with the other cpu (usually Wait For Interrupt, or WFI), and one or more "coupled" power states that affect blocks shared between the cpus (L2 cache, interrupt controller, and sometimes the whole SoC). Entering a coupled power state must be tightly controlled on both cpus β no cap, it's a whole coordinated moment π.
This file implements a solution, where each cpu will wait in the WFI state until all cpus are ready to enter a coupled state, at which point the coupled state function will be called on all cpus at approximately the same time.
Once all cpus are ready to enter idle, they are woken by an smp cross call. At this point, there is a chance that one of the cpus will find work to do, and choose not to enter idle. A final pass is needed to guarantee that all cpus will call the power state enter function at the same time. During this pass, each cpu will increment the ready counter, and continue once the ready counter matches the number of online coupled cpus. If any cpu exits idle, the other cpus will decrement their counter and retry. It's giving "everyone on the same beat or nobody moves" energy β¨.
requested_state stores the deepest coupled idle state each cpu is ready for. It is assumed that the states are indexed from shallowest (highest power, lowest exit latency) to deepest (lowest power, highest exit latency). The requested_state variable is not locked. It is only written from the cpu that it stores (or by the on/offlining cpu if that cpu is offline), and only read after all the cpus are ready for the coupled idle state are no longer updating it. Lowkey very specific, highkey very important π₯.
Three atomic counters are used:
alive_counttracks the number of cpus in the coupled set that are currently or soon will be online.waiting_counttracks the number of cpus that are in the waiting loop, in the ready loop, or in the coupled idle state.ready_counttracks the number of cpus that are in the ready loop or in the coupled idle state.
To use coupled cpuidle states, a cpuidle driver must: π
- Set
struct cpuidle_device.coupled_cpusto the mask of all coupled cpus, usually the same ascpu_possible_maskif all cpus are part of the same cluster. Thecoupled_cpusmask must be set in thestruct cpuidle_devicefor each cpu. - Set
struct cpuidle_device.safe_stateto a state that is not a coupled state. This is usuallyWFI. - Set
CPUIDLE_FLAG_COUPLEDinstruct cpuidle_state.flagsfor each state that affects multiple cpus. - Provide a
struct cpuidle_state.enterfunction for each state that affects multiple cpus. This function is guaranteed to be called on all cpus at approximately the same time. The driver should ensure that the cpus all abort together if any cpu tries to abort once the function is called. The function should return with interrupts still disabled.
π SEE ALSO π
- Kernel file
./drivers/cpuidle/coupled.c struct cpuidle_coupled(9)cpuidle_coupled_parallel_barrier(9)cpuidle_state_is_coupled(9)cpuidle_coupled_state_verify(9)cpuidle_coupled_set_ready(9)cpuidle_coupled_set_not_ready(9)cpuidle_coupled_no_cpus_ready(9)cpuidle_coupled_cpus_ready(9)cpuidle_coupled_cpus_waiting(9)cpuidle_coupled_no_cpus_waiting(9)cpuidle_coupled_get_state(9)cpuidle_coupled_poke(9)cpuidle_coupled_poke_others(9)cpuidle_coupled_set_waiting(9)cpuidle_coupled_set_not_waiting(9)cpuidle_coupled_set_done(9)cpuidle_coupled_clear_pokes(9)cpuidle_enter_state_coupled(9)cpuidle_coupled_register_device(9)cpuidle_coupled_unregister_device(9)cpuidle_coupled_prevent_idle(9)cpuidle_coupled_allow_idle(9)
okay that's the whole page, bestie π. Signing off from <pink>./drivers/cpuidle</pink> β wait, not inside the code block, we keep it cute: source is ./drivers/cpuidle, date is <yellow>October 2026</yellow>, and the title is Coupled cpuidle states(9)` π«Άβ¨ manual girl out π¦
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms