mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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 <pierre.gondois@arm.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
9ef0ad49cc
commit
e7a1b32e43
3 changed files with 30 additions and 36 deletions
|
@ -1544,7 +1544,7 @@ static int cpufreq_online(unsigned int cpu)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register with the energy model before
|
* Register with the energy model before
|
||||||
* sched_cpufreq_governor_change() is called, which will result
|
* sugov_eas_rebuild_sd() is called, which will result
|
||||||
* in rebuilding of the sched domains, which should only be done
|
* in rebuilding of the sched domains, which should only be done
|
||||||
* once the energy model is properly initialized for the policy
|
* once the energy model is properly initialized for the policy
|
||||||
* first.
|
* first.
|
||||||
|
@ -2652,7 +2652,6 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
||||||
ret = cpufreq_start_governor(policy);
|
ret = cpufreq_start_governor(policy);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
pr_debug("governor change\n");
|
pr_debug("governor change\n");
|
||||||
sched_cpufreq_governor_change(policy, old_gov);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cpufreq_exit_governor(policy);
|
cpufreq_exit_governor(policy);
|
||||||
|
|
|
@ -1193,14 +1193,6 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
|
|
||||||
void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
|
|
||||||
struct cpufreq_governor *old_gov);
|
|
||||||
#else
|
|
||||||
static inline void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
|
|
||||||
struct cpufreq_governor *old_gov) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern unsigned int arch_freq_get_on_cpu(int cpu);
|
extern unsigned int arch_freq_get_on_cpu(int cpu);
|
||||||
|
|
||||||
#ifndef arch_set_freq_scale
|
#ifndef arch_set_freq_scale
|
||||||
|
|
|
@ -555,6 +555,31 @@ static const struct kobj_type sugov_tunables_ktype = {
|
||||||
|
|
||||||
/********************** cpufreq governor interface *********************/
|
/********************** cpufreq governor interface *********************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ENERGY_MODEL
|
||||||
|
static void rebuild_sd_workfn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
rebuild_sched_domains_energy();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EAS shouldn't be attempted without sugov, so rebuild the sched_domains
|
||||||
|
* on governor changes to make sure the scheduler knows about it.
|
||||||
|
*/
|
||||||
|
static void sugov_eas_rebuild_sd(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* When called from the cpufreq_register_driver() path, the
|
||||||
|
* cpu_hotplug_lock is already held, so use a work item to
|
||||||
|
* avoid nested locking in rebuild_sched_domains().
|
||||||
|
*/
|
||||||
|
schedule_work(&rebuild_sd_work);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void sugov_eas_rebuild_sd(void) { };
|
||||||
|
#endif
|
||||||
|
|
||||||
struct cpufreq_governor schedutil_gov;
|
struct cpufreq_governor schedutil_gov;
|
||||||
|
|
||||||
static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy)
|
static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy)
|
||||||
|
@ -709,6 +734,8 @@ static int sugov_init(struct cpufreq_policy *policy)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
sugov_eas_rebuild_sd();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&global_tunables_lock);
|
mutex_unlock(&global_tunables_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -750,6 +777,8 @@ static void sugov_exit(struct cpufreq_policy *policy)
|
||||||
sugov_kthread_stop(sg_policy);
|
sugov_kthread_stop(sg_policy);
|
||||||
sugov_policy_free(sg_policy);
|
sugov_policy_free(sg_policy);
|
||||||
cpufreq_disable_fast_switch(policy);
|
cpufreq_disable_fast_switch(policy);
|
||||||
|
|
||||||
|
sugov_eas_rebuild_sd();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sugov_start(struct cpufreq_policy *policy)
|
static int sugov_start(struct cpufreq_policy *policy)
|
||||||
|
@ -833,29 +862,3 @@ struct cpufreq_governor *cpufreq_default_governor(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpufreq_governor_init(schedutil_gov);
|
cpufreq_governor_init(schedutil_gov);
|
||||||
|
|
||||||
#ifdef CONFIG_ENERGY_MODEL
|
|
||||||
static void rebuild_sd_workfn(struct work_struct *work)
|
|
||||||
{
|
|
||||||
rebuild_sched_domains_energy();
|
|
||||||
}
|
|
||||||
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EAS shouldn't be attempted without sugov, so rebuild the sched_domains
|
|
||||||
* on governor changes to make sure the scheduler knows about it.
|
|
||||||
*/
|
|
||||||
void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
|
|
||||||
struct cpufreq_governor *old_gov)
|
|
||||||
{
|
|
||||||
if (old_gov == &schedutil_gov || policy->governor == &schedutil_gov) {
|
|
||||||
/*
|
|
||||||
* When called from the cpufreq_register_driver() path, the
|
|
||||||
* cpu_hotplug_lock is already held, so use a work item to
|
|
||||||
* avoid nested locking in rebuild_sched_domains().
|
|
||||||
*/
|
|
||||||
schedule_work(&rebuild_sd_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue