[PATCH v2] cpufreq: Register with perf domain before

From: Vincent Wang
Date: Wed Jan 18 2023 - 00:03:28 EST


From: Vincent Wang <vincentwang3@xxxxxxxxxx>

We found the following issue during kernel boot on android phone:

[ 1.325272][ T1] cpu cpu0: EM: created perf domain
[ 1.329317][ T1] cpu cpu4: EM: created perf domain
[ 1.337597][ T76] pd_init: no EM found for CPU7
[ 1.350849][ T1] cpu cpu7: EM: created perf domain

pd init for cluster2 is executed in a kworker thread and
is earlier than the perf domain creation for cluster2.

pd_init() is called from the cpufreq notification of
CPUFREQ_CREATE_POLICY in cpufreq_online(), which is earlier
than that cpufreq_driver->register_em() is called.

To avoid this issue, register with perf domain should be
earlier than the notification is sent.

Signed-off-by: Vincent Wang <vincentwang3@xxxxxxxxxx>
---
v1 -> v2: based on Rafael's comment, adjust the order of
regitster perf domain. But I think it's no need to be in
advance to the initialization of frequency QoS.

Change the description of this patch.

drivers/cpufreq/cpufreq.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7e56a42750ea..a715c8323897 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1431,6 +1431,24 @@ static int cpufreq_online(unsigned int cpu)
goto out_destroy_policy;
}

+ /*
+ * Register with the energy model before
+ * blocking_notifier_call_chain() is called for
+ * CPUFREQ_CREATE_POLICY, which will result in rebuilding of the
+ * sched domains in update_topology_flags_workfn().
+ *
+ * Register with the energy model before
+ * sched_cpufreq_governor_change() is called, which will result
+ * in rebuilding of the sched domains, which should only be done
+ * once the energy model is properly initialized for the policy
+ * first.
+ *
+ * Also, this should be called before the policy is registered
+ * with cooling framework.
+ */
+ if (cpufreq_driver->register_em)
+ cpufreq_driver->register_em(policy);
+
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_CREATE_POLICY, policy);
}
@@ -1493,19 +1511,6 @@ static int cpufreq_online(unsigned int cpu)
write_lock_irqsave(&cpufreq_driver_lock, flags);
list_add(&policy->policy_list, &cpufreq_policy_list);
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
- /*
- * Register with the energy model before
- * sched_cpufreq_governor_change() is called, which will result
- * in rebuilding of the sched domains, which should only be done
- * once the energy model is properly initialized for the policy
- * first.
- *
- * Also, this should be called before the policy is registered
- * with cooling framework.
- */
- if (cpufreq_driver->register_em)
- cpufreq_driver->register_em(policy);
}

ret = cpufreq_init_policy(policy);
--
2.25.1