diff options
author | Mike Galbraith <efault@gmx.de> | 2009-10-09 02:35:03 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-10-09 09:58:11 -0400 |
commit | f5dc37530ba8a35aae0f7f4f13781d1904f71e94 (patch) | |
tree | 866894f6bf41876a7c6096912c82e73d140d3071 | |
parent | 36a07902c2134649c4af7f07980413ffb1a56085 (diff) |
sched: Update the clock of runqueue select_task_rq() selected
In try_to_wake_up(), we update the runqueue clock, but
select_task_rq() may select a different runqueue than the one we
updated, leaving the new runqueue's clock stale for a bit.
This patch cures occasional huge latencies reported by latencytop
when coming out of idle on a mostly idle NO_HZ box.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1255070103.7639.30.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/sched.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 76c0e9691fc0..e3f8f4f61c8e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2311,7 +2311,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2311 | { | 2311 | { |
2312 | int cpu, orig_cpu, this_cpu, success = 0; | 2312 | int cpu, orig_cpu, this_cpu, success = 0; |
2313 | unsigned long flags; | 2313 | unsigned long flags; |
2314 | struct rq *rq; | 2314 | struct rq *rq, *orig_rq; |
2315 | 2315 | ||
2316 | if (!sched_feat(SYNC_WAKEUPS)) | 2316 | if (!sched_feat(SYNC_WAKEUPS)) |
2317 | wake_flags &= ~WF_SYNC; | 2317 | wake_flags &= ~WF_SYNC; |
@@ -2319,7 +2319,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2319 | this_cpu = get_cpu(); | 2319 | this_cpu = get_cpu(); |
2320 | 2320 | ||
2321 | smp_wmb(); | 2321 | smp_wmb(); |
2322 | rq = task_rq_lock(p, &flags); | 2322 | rq = orig_rq = task_rq_lock(p, &flags); |
2323 | update_rq_clock(rq); | 2323 | update_rq_clock(rq); |
2324 | if (!(p->state & state)) | 2324 | if (!(p->state & state)) |
2325 | goto out; | 2325 | goto out; |
@@ -2350,6 +2350,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2350 | set_task_cpu(p, cpu); | 2350 | set_task_cpu(p, cpu); |
2351 | 2351 | ||
2352 | rq = task_rq_lock(p, &flags); | 2352 | rq = task_rq_lock(p, &flags); |
2353 | |||
2354 | if (rq != orig_rq) | ||
2355 | update_rq_clock(rq); | ||
2356 | |||
2353 | WARN_ON(p->state != TASK_WAKING); | 2357 | WARN_ON(p->state != TASK_WAKING); |
2354 | cpu = task_cpu(p); | 2358 | cpu = task_cpu(p); |
2355 | 2359 | ||