summaryrefslogtreecommitdiff
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-09-10 12:40:57 (GMT)
committerIngo Molnar <mingo@elte.hu>2009-09-15 14:01:06 (GMT)
commitae154be1f34a674e6cbb43ccf6e442f56acd7a70 (patch)
treee1feba2c818216c97e11801ee7a6e3c2592b10af /kernel/sched_fair.c
parentc88d5910890ad35af283344417891344604f0438 (diff)
downloadlinux-ae154be1f34a674e6cbb43ccf6e442f56acd7a70.tar.xz
sched: Weaken SD_POWERSAVINGS_BALANCE
One of the problems of power-saving balancing is that under certain scenarios it is too slow and allows tons of real work to pile up. Avoid this by ignoring the powersave stuff when there's real work to be done. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
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 09d19f7..eaa0001 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: