summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorSrivatsa Vaddagiri <vatsa@codeaurora.org>2014-06-12 01:22:20 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 19:59:38 -0700
commit01cb5df240a6ef02b810f3fee1012983aee0aa80 (patch)
tree2211b7e75b225ef39902be6d86abf2914488c522 /kernel
parent77952197a6f3836af929de42dd1659080a1b1d3a (diff)
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 <vatsa@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/core.c63
1 files 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();