aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
authorMike Galbraith <efault@gmx.de>2008-05-29 05:11:41 -0400
committerIngo Molnar <mingo@elte.hu>2008-05-29 05:29:20 -0400
commitb3137bc8e77962a8e3b4dfdc1bcfd38e437bd278 (patch)
tree5131501b5575f933074cc89545ff997d277d1d57 /kernel/sched_fair.c
parenta381759d6ad5c5dea5a981918e0b4493e9b66ac7 (diff)
sched: stop wake_affine from causing serious imbalance
Prevent short-running wakers of short-running threads from overloading a single cpu via wakeup affinity, and wire up disconnected debug option. Signed-off-by: Mike Galbraith <efault@gmx.de> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index f0f25fc12d0a..08ae848b71d4 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -996,16 +996,27 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq,
996 struct task_struct *curr = this_rq->curr; 996 struct task_struct *curr = this_rq->curr;
997 unsigned long tl = this_load; 997 unsigned long tl = this_load;
998 unsigned long tl_per_task; 998 unsigned long tl_per_task;
999 int balanced;
999 1000
1000 if (!(this_sd->flags & SD_WAKE_AFFINE)) 1001 if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
1001 return 0; 1002 return 0;
1002 1003
1003 /* 1004 /*
1005 * If sync wakeup then subtract the (maximum possible)
1006 * effect of the currently running task from the load
1007 * of the current CPU:
1008 */
1009 if (sync)
1010 tl -= current->se.load.weight;
1011
1012 balanced = 100*(tl + p->se.load.weight) <= imbalance*load;
1013
1014 /*
1004 * If the currently running task will sleep within 1015 * If the currently running task will sleep within
1005 * a reasonable amount of time then attract this newly 1016 * a reasonable amount of time then attract this newly
1006 * woken task: 1017 * woken task:
1007 */ 1018 */
1008 if (sync && curr->sched_class == &fair_sched_class) { 1019 if (sync && balanced && curr->sched_class == &fair_sched_class) {
1009 if (curr->se.avg_overlap < sysctl_sched_migration_cost && 1020 if (curr->se.avg_overlap < sysctl_sched_migration_cost &&
1010 p->se.avg_overlap < sysctl_sched_migration_cost) 1021 p->se.avg_overlap < sysctl_sched_migration_cost)
1011 return 1; 1022 return 1;
@@ -1014,16 +1025,8 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq,
1014 schedstat_inc(p, se.nr_wakeups_affine_attempts); 1025 schedstat_inc(p, se.nr_wakeups_affine_attempts);
1015 tl_per_task = cpu_avg_load_per_task(this_cpu); 1026 tl_per_task = cpu_avg_load_per_task(this_cpu);
1016 1027
1017 /*
1018 * If sync wakeup then subtract the (maximum possible)
1019 * effect of the currently running task from the load
1020 * of the current CPU:
1021 */
1022 if (sync)
1023 tl -= current->se.load.weight;
1024
1025 if ((tl <= load && tl + target_load(prev_cpu, idx) <= tl_per_task) || 1028 if ((tl <= load && tl + target_load(prev_cpu, idx) <= tl_per_task) ||
1026 100*(tl + p->se.load.weight) <= imbalance*load) { 1029 balanced) {
1027 /* 1030 /*
1028 * This domain has SD_WAKE_AFFINE and 1031 * This domain has SD_WAKE_AFFINE and
1029 * p is cache cold in this domain, and 1032 * p is cache cold in this domain, and