sched: Clarify ordering between task_rq_lock() and move_queued_task()
There was a wee bit of confusion around the exact ordering here; clarify things. Reported-by: Kirill Tkhai <ktkhai@parallels.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/20150217121258.GM5029@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
e07e0d4cb0
Коммит
74b8a4cb6c
|
@ -341,6 +341,22 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags)
|
||||||
raw_spin_lock_irqsave(&p->pi_lock, *flags);
|
raw_spin_lock_irqsave(&p->pi_lock, *flags);
|
||||||
rq = task_rq(p);
|
rq = task_rq(p);
|
||||||
raw_spin_lock(&rq->lock);
|
raw_spin_lock(&rq->lock);
|
||||||
|
/*
|
||||||
|
* move_queued_task() task_rq_lock()
|
||||||
|
*
|
||||||
|
* ACQUIRE (rq->lock)
|
||||||
|
* [S] ->on_rq = MIGRATING [L] rq = task_rq()
|
||||||
|
* WMB (__set_task_cpu()) ACQUIRE (rq->lock);
|
||||||
|
* [S] ->cpu = new_cpu [L] task_rq()
|
||||||
|
* [L] ->on_rq
|
||||||
|
* RELEASE (rq->lock)
|
||||||
|
*
|
||||||
|
* If we observe the old cpu in task_rq_lock, the acquire of
|
||||||
|
* the old rq->lock will fully serialize against the stores.
|
||||||
|
*
|
||||||
|
* If we observe the new cpu in task_rq_lock, the acquire will
|
||||||
|
* pair with the WMB to ensure we must then also see migrating.
|
||||||
|
*/
|
||||||
if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
|
if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
|
||||||
return rq;
|
return rq;
|
||||||
raw_spin_unlock(&rq->lock);
|
raw_spin_unlock(&rq->lock);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче