summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Muckle <smuckle@codeaurora.org>2014-03-25 14:34:41 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 19:59:24 -0700
commit9931863046ec2ba6c79838e3b8bb0839b1104aa8 (patch)
treeefaec5a54f45d7a2fa5683bc3a3c4a8e4ed34393
parenta31debf1c93cc87f60915e06d00889a8a047656e (diff)
sched: do nohz load balancing in order of power efficiency
The nohz load balancer CPU does load balancing on behalf of all idle tickless CPUs. In the interest of power efficiency though, we should do load balancing on the most power efficient idle tickless CPU first, and then work our way towards the least power efficient idle tickless CPU. This will help load find its way to the most power efficient CPUs in the system. Since when selecting the CPU to balance next it is unknown what task load would be pulled, a frequency must be assumed in order to do a comparison of CPU power consumption. The maximum freqeuncy supported by all CPUs is used for this. Change-Id: I96c7f4300fde2c677c068dc10fc0e57f763eb9b2 Signed-off-by: Steve Muckle <smuckle@codeaurora.org> Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org> [joonwoop@codeaurora.org: fixed minor conflict in nohz_idle_balance().] Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
-rw-r--r--kernel/sched/fair.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 2cb70c88d18a..bb6704e0ee09 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8532,6 +8532,28 @@ out:
}
#ifdef CONFIG_NO_HZ_COMMON
+
+static int select_lowest_power_cpu(struct cpumask *cpus)
+{
+ int i, cost;
+ int lowest_power_cpu = -1;
+ int lowest_power = INT_MAX;
+
+ if (sysctl_sched_enable_power_aware) {
+ for_each_cpu(i, cpus) {
+ cost = power_cost_at_freq(i, 0);
+ if (cost < lowest_power) {
+ lowest_power_cpu = i;
+ lowest_power = cost;
+ }
+ }
+ BUG_ON(lowest_power_cpu == -1);
+ return lowest_power_cpu;
+ } else {
+ return cpumask_first(cpus);
+ }
+}
+
/*
* In CONFIG_NO_HZ_COMMON case, the idle balance kickee will do the
* rebalancing for all the cpus for whom scheduler ticks are stopped.
@@ -8544,12 +8566,18 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
/* Earliest time when we have to do rebalance again */
unsigned long next_balance = jiffies + 60*HZ;
int update_next_balance = 0;
+ struct cpumask cpus_to_balance;
if (idle != CPU_IDLE ||
!test_bit(NOHZ_BALANCE_KICK, nohz_flags(this_cpu)))
goto end;
- for_each_cpu(balance_cpu, nohz.idle_cpus_mask) {
+ cpumask_copy(&cpus_to_balance, nohz.idle_cpus_mask);
+
+ while (!cpumask_empty(&cpus_to_balance)) {
+ balance_cpu = select_lowest_power_cpu(&cpus_to_balance);
+
+ cpumask_clear_cpu(balance_cpu, &cpus_to_balance);
if (balance_cpu == this_cpu || !idle_cpu(balance_cpu))
continue;