From 01cb5df240a6ef02b810f3fee1012983aee0aa80 Mon Sep 17 00:00:00 2001 From: Srivatsa Vaddagiri Date: Thu, 12 Jun 2014 01:22:20 -0700 Subject: sched: Update capacity of all online cpus when min_max_freq changes During bootup, its possible for min_max_freq to change as frequency information for additional clusters is processed. That would need to trigger recalculation of capacity/load_scale_factor for all (online) cpus, as they strongly depend on min_max_freq variable. Not doing so would imply some cpus will have their capacity/load_scale_factor computed wrongly. Change-Id: Iea5a0a517a2d71be24c2c71cdd805c0733ce37f8 Signed-off-by: Srivatsa Vaddagiri --- kernel/sched/core.c | 63 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index a38cd7962fb3..4567e413fb69 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8078,15 +8078,46 @@ static inline unsigned long load_scale_cpu_freq(int cpu) return (1024 * max_possible_freq) / cpu_rq(cpu)->max_freq; } +static int compute_capacity(int cpu) +{ + int capacity = 1024; + + capacity *= capacity_scale_cpu_efficiency(cpu); + capacity >>= 10; + + capacity *= capacity_scale_cpu_freq(cpu); + capacity >>= 10; + + return capacity; +} + +static int compute_load_scale_factor(int cpu) +{ + int load_scale = 1024; + + /* + * load_scale_factor accounts for the fact that task load + * is in reference to "best" performing cpu. Task's load will need to be + * scaled (up) by a factor to determine suitability to be placed on a + * (little) cpu. + */ + load_scale *= load_scale_cpu_efficiency(cpu); + load_scale >>= 10; + + load_scale *= load_scale_cpu_freq(cpu); + load_scale >>= 10; + + return load_scale; +} + static int cpufreq_notifier_policy(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_policy *policy = (struct cpufreq_policy *)data; int i; unsigned int min_max = min_max_freq; - int cpu = policy->cpu; - int load_scale = 1024; - int capacity = 1024; + const struct cpumask *cpus = policy->related_cpus; + int orig_min_max_freq = min_max_freq; if (val != CPUFREQ_NOTIFY) return 0; @@ -8106,24 +8137,8 @@ static int cpufreq_notifier_policy(struct notifier_block *nb, BUG_ON(!min_max_freq); BUG_ON(!policy->max); - /* Assumes all cpus in cluster has same efficiency!! */ - capacity *= capacity_scale_cpu_efficiency(cpu); - capacity >>= 10; - - capacity *= capacity_scale_cpu_freq(cpu); - capacity >>= 10; - - /* - * load_scale_factor accounts for the fact that task load - * (p->se.avg.runnable_avg_sum_scaled) is in reference to "best" - * performing cpu. Task's load will need to be scaled (up) by a factor - * to determine suitability to be placed on a particular cpu. - */ - load_scale *= load_scale_cpu_efficiency(cpu); - load_scale >>= 10; - - load_scale *= load_scale_cpu_freq(cpu); - load_scale >>= 10; + if (min_max_freq != orig_min_max_freq) + cpus = cpu_online_mask; /* * Changed load_scale_factor can trigger reclassification of tasks as @@ -8131,11 +8146,11 @@ static int cpufreq_notifier_policy(struct notifier_block *nb, * properly due to changed load_scale_factor */ pre_big_small_task_count_change(); - for_each_cpu(i, policy->related_cpus) { + for_each_cpu(i, cpus) { struct rq *rq = cpu_rq(i); - rq->capacity = capacity; - rq->load_scale_factor = load_scale; + rq->capacity = compute_capacity(i); + rq->load_scale_factor = compute_load_scale_factor(i); } update_min_max_capacity(); -- cgit v1.2.3