diff options
author | Mike Galbraith <efault@gmx.de> | 2008-05-29 05:11:41 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-05-29 05:29:20 -0400 |
commit | b3137bc8e77962a8e3b4dfdc1bcfd38e437bd278 (patch) | |
tree | 5131501b5575f933074cc89545ff997d277d1d57 /kernel/sched_fair.c | |
parent | a381759d6ad5c5dea5a981918e0b4493e9b66ac7 (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.c | 25 |
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 |