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

Maulik Shah <[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 <[email protected]>
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
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.

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]>
---
 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.