Skip to content

Commit e7a1b32

Browse files
pierregondoisrafaeljw
authored andcommitted
cpufreq: Rebuild sched-domains when removing cpufreq driver
The Energy Aware Scheduler (EAS) relies on the schedutil governor. When moving to/from the schedutil governor, sched domains must be rebuilt to allow re-evaluating the enablement conditions of EAS. This is done through sched_cpufreq_governor_change(). Having a cpufreq governor assumes a cpufreq driver is running. Inserting/removing a cpufreq driver should trigger a re-evaluation of EAS enablement conditions, avoiding to see EAS enabled when removing a running cpufreq driver. Rebuild the sched domains in schedutil's sugov_init()/sugov_exit(), allowing to check EAS's enablement condition whenever schedutil governor is initialized/exited from. Move relevant code up in schedutil.c to avoid a split and conditional function declaration. Rename sched_cpufreq_governor_change() to sugov_eas_rebuild_sd(). Signed-off-by: Pierre Gondois <[email protected]> Acked-by: Viresh Kumar <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 9ef0ad4 commit e7a1b32

File tree

3 files changed

+30
-36
lines changed

3 files changed

+30
-36
lines changed

drivers/cpufreq/cpufreq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,7 @@ static int cpufreq_online(unsigned int cpu)
15441544

15451545
/*
15461546
* Register with the energy model before
1547-
* sched_cpufreq_governor_change() is called, which will result
1547+
* sugov_eas_rebuild_sd() is called, which will result
15481548
* in rebuilding of the sched domains, which should only be done
15491549
* once the energy model is properly initialized for the policy
15501550
* first.
@@ -2652,7 +2652,6 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
26522652
ret = cpufreq_start_governor(policy);
26532653
if (!ret) {
26542654
pr_debug("governor change\n");
2655-
sched_cpufreq_governor_change(policy, old_gov);
26562655
return 0;
26572656
}
26582657
cpufreq_exit_governor(policy);

include/linux/cpufreq.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,14 +1193,6 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
11931193
}
11941194
#endif
11951195

1196-
#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
1197-
void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
1198-
struct cpufreq_governor *old_gov);
1199-
#else
1200-
static inline void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
1201-
struct cpufreq_governor *old_gov) { }
1202-
#endif
1203-
12041196
extern unsigned int arch_freq_get_on_cpu(int cpu);
12051197

12061198
#ifndef arch_set_freq_scale

kernel/sched/cpufreq_schedutil.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,31 @@ static const struct kobj_type sugov_tunables_ktype = {
555555

556556
/********************** cpufreq governor interface *********************/
557557

558+
#ifdef CONFIG_ENERGY_MODEL
559+
static void rebuild_sd_workfn(struct work_struct *work)
560+
{
561+
rebuild_sched_domains_energy();
562+
}
563+
564+
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
565+
566+
/*
567+
* EAS shouldn't be attempted without sugov, so rebuild the sched_domains
568+
* on governor changes to make sure the scheduler knows about it.
569+
*/
570+
static void sugov_eas_rebuild_sd(void)
571+
{
572+
/*
573+
* When called from the cpufreq_register_driver() path, the
574+
* cpu_hotplug_lock is already held, so use a work item to
575+
* avoid nested locking in rebuild_sched_domains().
576+
*/
577+
schedule_work(&rebuild_sd_work);
578+
}
579+
#else
580+
static inline void sugov_eas_rebuild_sd(void) { };
581+
#endif
582+
558583
struct cpufreq_governor schedutil_gov;
559584

560585
static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy)
@@ -709,6 +734,8 @@ static int sugov_init(struct cpufreq_policy *policy)
709734
if (ret)
710735
goto fail;
711736

737+
sugov_eas_rebuild_sd();
738+
712739
out:
713740
mutex_unlock(&global_tunables_lock);
714741
return 0;
@@ -750,6 +777,8 @@ static void sugov_exit(struct cpufreq_policy *policy)
750777
sugov_kthread_stop(sg_policy);
751778
sugov_policy_free(sg_policy);
752779
cpufreq_disable_fast_switch(policy);
780+
781+
sugov_eas_rebuild_sd();
753782
}
754783

755784
static int sugov_start(struct cpufreq_policy *policy)
@@ -833,29 +862,3 @@ struct cpufreq_governor *cpufreq_default_governor(void)
833862
#endif
834863

835864
cpufreq_governor_init(schedutil_gov);
836-
837-
#ifdef CONFIG_ENERGY_MODEL
838-
static void rebuild_sd_workfn(struct work_struct *work)
839-
{
840-
rebuild_sched_domains_energy();
841-
}
842-
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
843-
844-
/*
845-
* EAS shouldn't be attempted without sugov, so rebuild the sched_domains
846-
* on governor changes to make sure the scheduler knows about it.
847-
*/
848-
void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
849-
struct cpufreq_governor *old_gov)
850-
{
851-
if (old_gov == &schedutil_gov || policy->governor == &schedutil_gov) {
852-
/*
853-
* When called from the cpufreq_register_driver() path, the
854-
* cpu_hotplug_lock is already held, so use a work item to
855-
* avoid nested locking in rebuild_sched_domains().
856-
*/
857-
schedule_work(&rebuild_sd_work);
858-
}
859-
860-
}
861-
#endif

0 commit comments

Comments
 (0)