[03/14] sched: cpufreq: Introduce 'want_eas' governor flag

Message ID 20200507181012.29791-4-qperret@google.com
State New
Headers show
Series
  • Untitled series #38279
Related show

Commit Message

Quentin Perret May 7, 2020, 6:10 p.m.
The EAS topology code requires the usage of schedutil on all CPUs of an
rd to actually enable EAS balancing. However, the check implementing
this references the schedutil_gov struct directly, which makes having
schedutil as a module impractical.

To prepare the ground for this modularization, introduce a new
'want_eas' flag in the cpufreq_governor struct, set it for schedutil
only, and make sure to check it from the EAS topology code.

Signed-off-by: Quentin Perret <qperret@google.com>
---
 include/linux/cpufreq.h          |  4 ++++
 kernel/sched/cpufreq_schedutil.c |  5 ++++-
 kernel/sched/topology.c          | 12 ++++++------
 3 files changed, 14 insertions(+), 7 deletions(-)

Patch

diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index f7240251a949..267cc3b624da 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -560,6 +560,10 @@  struct cpufreq_governor {
 	bool			dynamic_switching;
 	struct list_head	governor_list;
 	struct module		*owner;
+
+#ifdef CONFIG_ENERGY_MODEL
+	bool			want_eas;
+#endif /* CONFIG_ENERGY_MODEL */
 };
 
 /* Pass a target to the cpufreq driver */
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index ebd5d30f0861..c5e5045f7c81 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -888,6 +888,9 @@  struct cpufreq_governor schedutil_gov = {
 	.start			= sugov_start,
 	.stop			= sugov_stop,
 	.limits			= sugov_limits,
+#ifdef CONFIG_ENERGY_MODEL
+	.want_eas		= true,
+#endif /* CONFIG_ENERGY_MODEL */
 };
 
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
@@ -924,7 +927,7 @@  static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
 void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
 				  struct cpufreq_governor *old_gov)
 {
-	if (old_gov == &schedutil_gov || policy->governor == &schedutil_gov) {
+	if ((old_gov && old_gov->want_eas) || policy->governor->want_eas) {
 		/*
 		 * When called from the cpufreq_register_driver() path, the
 		 * cpu_hotplug_lock is already held, so use a work item to
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 8344757bba6e..b905f2e8d9b2 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -319,7 +319,8 @@  static void sched_energy_set(bool has_eas)
  *    2. the SD_ASYM_CPUCAPACITY flag is set in the sched_domain hierarchy.
  *    3. no SMT is detected.
  *    4. the EM complexity is low enough to keep scheduling overheads low;
- *    5. schedutil is driving the frequency of all CPUs of the rd;
+ *    5. an EAS-compatible CPUfreq governor (schedutil) is driving the frequency
+ *       of all CPUs of the rd;
  *
  * The complexity of the Energy Model is defined as:
  *
@@ -339,7 +340,6 @@  static void sched_energy_set(bool has_eas)
  */
 #define EM_MAX_COMPLEXITY 2048
 
-extern struct cpufreq_governor schedutil_gov;
 static bool build_perf_domains(const struct cpumask *cpu_map)
 {
 	int i, nr_pd = 0, nr_cs = 0, nr_cpus = cpumask_weight(cpu_map);
@@ -347,7 +347,7 @@  static bool build_perf_domains(const struct cpumask *cpu_map)
 	int cpu = cpumask_first(cpu_map);
 	struct root_domain *rd = cpu_rq(cpu)->rd;
 	struct cpufreq_policy *policy;
-	struct cpufreq_governor *gov;
+	bool want_eas;
 
 	if (!sysctl_sched_energy_aware)
 		goto free;
@@ -377,11 +377,11 @@  static bool build_perf_domains(const struct cpumask *cpu_map)
 		policy = cpufreq_cpu_get(i);
 		if (!policy)
 			goto free;
-		gov = policy->governor;
+		want_eas = policy->governor && policy->governor->want_eas;
 		cpufreq_cpu_put(policy);
-		if (gov != &schedutil_gov) {
+		if (!want_eas) {
 			if (rd->pd)
-				pr_warn("rd %*pbl: Disabling EAS, schedutil is mandatory\n",
+				pr_warn("rd %*pbl: Disabling EAS because of incompatible CPUFreq governor\n",
 						cpumask_pr_args(cpu_map));
 			goto free;
 		}