summaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 09d19f77eb3..eaa00014b49 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1333,10 +1333,25 @@ static int select_task_rq_fair(struct task_struct *p, int flag, int sync)
for_each_domain(cpu, tmp) {
/*
- * If power savings logic is enabled for a domain, stop there.
+ * If power savings logic is enabled for a domain, see if we
+ * are not overloaded, if so, don't balance wider.
*/
- if (tmp->flags & SD_POWERSAVINGS_BALANCE)
- break;
+ if (tmp->flags & SD_POWERSAVINGS_BALANCE) {
+ unsigned long power = 0;
+ unsigned long nr_running = 0;
+ unsigned long capacity;
+ int i;
+
+ for_each_cpu(i, sched_domain_span(tmp)) {
+ power += power_of(i);
+ nr_running += cpu_rq(i)->cfs.nr_running;
+ }
+
+ capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
+
+ if (nr_running/2 < capacity)
+ break;
+ }
switch (flag) {
case SD_BALANCE_WAKE: