Re: [PATCH 1/2] cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used

Ulf Hansson <[email protected]>
Newsgroups org.kernel.vger.linux-pm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel
Message-ID <CAPx+jO_Z6woSz_ywFjNLhvEgYyBQR89+trK+6kL6Q1aPxsWtwA@mail.gmail.com>
On Tue, Aug 11, 2026 at 7:50 AM Maulik Shah
<[email protected]> wrote:
>
> psci_pd_init() always calls pm_genpd_init() with is_off=false, so a
> CPU-cluster pmdomain is marked ON at creation regardless of whether any
> CPU has actually powered it on yet. The pmdomain's own status tracking
> (and the power-on notifier chain fired from _genpd_power_on()) is
> therefore wrong from the outset for OSI mode.
>
> A concrete example: hamoa has 3 CPU clusters, each with 4 CPUs, under a
> single parent system-level pmdomain. Passing "maxcpus=4" on the kernel
> command line limits boot to the first 4 CPUs, so only cluster0 is ever
> actually powered on. Without this fix, cluster1 and cluster2 are still
> marked ON at creation regardless, since is_off is always false. Because
> none of their CPUs ever come online, neither dt_idle_attach_cpu() nor
> psci_idle_cpuhp_up() ever fires for them, so nothing subsequently

Why isn't dt_idle_attach_cpu() called for them?

If we pass "maxcpus=4" on the kernel command line, the
cpu_present_mask should still contain all CPUs which cpuidle-psci uses
when attaching CPU devices to their respective CPU PM domain. Or maybe
I am wrong here?

> drives those two domains to OFF - they stay marked ON for as long as
> the system runs. When cluster0's CPUs go idle and its pmdomain is
> powered off, the parent system-level pmdomain still sees cluster1 and
> cluster2 as ON and therefore never selects a system-level idle state,
> even though no CPU in those two clusters ever executed.

Doesn't genpd_provider_sync_state() get called for these domains,
allowing them to be turned off?

>
> Starting the domain OFF is safe under OSI:
>
>  - For CPUs already online by the time this driver probes,
>    dt_idle_attach_cpu() explicitly checks cpu_online() and calls
>    pm_runtime_get_sync() on the CPU's attach device, which resolves to
>    this same pmdomain and drives a real power-on immediately. This runs
>    from psci_cpuidle_probe(), a device_initcall, strictly after
>    psci_idle_init_domains()'s core_initcall has already created and
>    marked off every pmdomain, so there is no window where an online
>    CPU's domain is left off with nothing left to turn it on.
>
>  - For CPUs that come online later, psci_idle_cpuhp_up() (registered
>    via cpuhp_setup_state_nocalls(), which never invokes the callback
>    for already-online CPUs at registration time) powers the domain on
>    through the normal cpuhp AP_ONLINE path.
>
> Gate this on use_osi rather than applying it unconditionally: in
> non-OSI mode psci_pd_init() sets GENPD_FLAG_ALWAYS_ON, which
> independently blocks genpd_power_off() regardless of is_off, so the
> domain can never really be off there and marking it is_off=true would
> be misleading noise with no effect.
>
> Fixes: a65a397f2451 ("cpuidle: psci: Add support for PM domains by using genpd")
> Assisted-by: Claude:claude-sonnet-5
> Signed-off-by: Maulik Shah <[email protected]>

Kind regards
Uffe

> ---
>  drivers/cpuidle/cpuidle-psci-domain.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
> index b9e4ad7d43a3..fab9de648b17 100644
> --- a/drivers/cpuidle/cpuidle-psci-domain.c
> +++ b/drivers/cpuidle/cpuidle-psci-domain.c
> @@ -78,7 +78,19 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
>         /* Use governor for CPU PM domains if it has some states to manage. */
>         pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
>
> -       ret = pm_genpd_init(pd, pd_gov, false);
> +       /*
> +        * Start the domain in the OFF state when OSI is in use, so that
> +        * genpd's own status tracking (and its power-on notifier chain)
> +        * reflects reality from the outset instead of reporting ON before
> +        * any CPU in the domain has actually requested it. This is safe:
> +        * dt_idle_attach_cpu() runtime-resumes the domain for every CPU
> +        * that is already online by the time this driver probes, and the
> +        * PSCI cpuidle cpuhp callbacks power it on/off for CPUs that come
> +        * online/offline afterwards. When OSI isn't in use, GENPD_FLAG_ALWAYS_ON
> +        * above keeps the domain powered regardless of is_off, so this has
> +        * no effect there.
> +        */
> +       ret = pm_genpd_init(pd, pd_gov, use_osi);
>         if (ret)
>                 goto free_pd_prov;
>
>
> --
> 2.43.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.