Commit 01c8df04 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

[PATCH] fix wait_task_inactive race

When a task is put to sleep, it is dequeued from the runqueue while it is
still running.  The problem is that one some arches that have non-atomic
scheduling, the runqueue lock can be dropped and retaken in schedule() before
the task actually schedules off, and wait_task_inactive did not account for
this.
Signed-off-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 73f54a78
...@@ -867,7 +867,7 @@ void wait_task_inactive(task_t * p) ...@@ -867,7 +867,7 @@ void wait_task_inactive(task_t * p)
repeat: repeat:
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
/* Must be off runqueue entirely, not preempted. */ /* Must be off runqueue entirely, not preempted. */
if (unlikely(p->array)) { if (unlikely(p->array || task_running(rq, p))) {
/* If it's preempted, we yield. It could be a while. */ /* If it's preempted, we yield. It could be a while. */
preempted = !task_running(rq, p); preempted = !task_running(rq, p);
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment