mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
sched/wait: Fix rcuwait_wake_up() ordering
For some peculiar reason rcuwait_wake_up() has the right barrier in
the comment, but not in the code.
This mistake has been observed to cause a deadlock in the following
situation:
P1 P2
percpu_up_read() percpu_down_write()
rcu_sync_is_idle() // false
rcu_sync_enter()
...
__percpu_up_read()
[S] ,- __this_cpu_dec(*sem->read_count)
| smp_rmb();
[L] | task = rcu_dereference(w->task) // NULL
|
| [S] w->task = current
| smp_mb();
| [L] readers_active_check() // fail
`-> <store happens here>
Where the smp_rmb() (obviously) fails to constrain the store.
[ peterz: Added changelog. ]
Signed-off-by: Prateek Sood <prsood@codeaurora.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Andrea Parri <andrea.parri@amarulasolutions.com>
Acked-by: Davidlohr Bueso <dbueso@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 8f95c90ceb
("sched/wait, RCU: Introduce rcuwait machinery")
Link: https://lkml.kernel.org/r/1543590656-7157-1-git-send-email-prsood@codeaurora.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
d7393226d1
commit
6dc080eeb2
@ -307,7 +307,7 @@ void rcuwait_wake_up(struct rcuwait *w)
|
||||
* MB (A) MB (B)
|
||||
* [L] cond [L] tsk
|
||||
*/
|
||||
smp_rmb(); /* (B) */
|
||||
smp_mb(); /* (B) */
|
||||
|
||||
/*
|
||||
* Avoid using task_rcu_dereference() magic as long as we are careful,
|
||||
|
Loading…
Reference in New Issue
Block a user