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 <qper...@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(-)

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;
                }
-- 
2.26.2.526.g744177e7f7-goog

Reply via email to