|author||Andrea Parri <firstname.lastname@example.org>||2018-07-16 11:06:03 -0700|
|committer||Ingo Molnar <email@example.com>||2018-07-17 09:30:34 +0200|
sched/Documentation: Update wake_up() & co. memory-barrier guarantees
Both the implementation and the users' expectation  for the various wakeup primitives have evolved over time, but the documentation has not kept up with these changes: brings it into 2018.  http://lkml.kernel.org/r/20180424091510.GB4064@hirez.programming.kicks-ass.net Also applied feedback from Alan Stern. Suggested-by: Peter Zijlstra <firstname.lastname@example.org> Signed-off-by: Andrea Parri <email@example.com> Signed-off-by: Paul E. McKenney <firstname.lastname@example.org> Acked-by: Peter Zijlstra (Intel) <email@example.com> Cc: Akira Yokosawa <firstname.lastname@example.org> Cc: Alan Stern <email@example.com> Cc: Boqun Feng <firstname.lastname@example.org> Cc: Daniel Lustig <email@example.com> Cc: David Howells <firstname.lastname@example.org> Cc: Jade Alglave <email@example.com> Cc: Jonathan Corbet <firstname.lastname@example.org> Cc: Linus Torvalds <email@example.com> Cc: Luc Maranget <firstname.lastname@example.org> Cc: Nicholas Piggin <email@example.com> Cc: Thomas Gleixner <firstname.lastname@example.org> Cc: Will Deacon <email@example.com> Cc: firstname.lastname@example.org Cc: email@example.com Link: http://firstname.lastname@example.org Signed-off-by: Ingo Molnar <email@example.com>
Diffstat (limited to 'Documentation/memory-barriers.txt')
1 files changed, 27 insertions, 16 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index a02d6bbfc9d0..0d8d7ef131e9 100644
@@ -2179,32 +2179,41 @@ or:
event_indicated = 1;
-A write memory barrier is implied by wake_up() and co. if and only if they
-wake something up. The barrier occurs before the task state is cleared, and so
-sits between the STORE to indicate the event and the STORE to set TASK_RUNNING:
+A general memory barrier is executed by wake_up() if it wakes something up.
+If it doesn't wake anything up then a memory barrier may or may not be
+executed; you must not rely on it. The barrier occurs before the task state
+is accessed, in particular, it sits between the STORE to indicate the event
+and the STORE to set TASK_RUNNING:
- CPU 1 CPU 2
+ CPU 1 (Sleeper) CPU 2 (Waker)
set_current_state(); STORE event_indicated
- STORE current->state <write barrier>
- <general barrier> STORE current->state
- LOAD event_indicated
+ STORE current->state ...
+ <general barrier> <general barrier>
+ LOAD event_indicated if ((LOAD task->state) & TASK_NORMAL)
+ STORE task->state
-To repeat, this write memory barrier is present if and only if something
-is actually awakened. To see this, consider the following sequence of
-events, where X and Y are both initially zero:
+where "task" is the thread being woken up and it equals CPU 1's "current".
+To repeat, a general memory barrier is guaranteed to be executed by wake_up()
+if something is actually awakened, but otherwise there is no such guarantee.
+To see this, consider the following sequence of events, where X and Y are both
CPU 1 CPU 2
- X = 1; STORE event_indicated
+ X = 1; Y = 1;
- Y = 1; wait_event(wq, Y == 1);
- wake_up(); load from Y sees 1, no memory barrier
- load from X might see 0
+ LOAD Y LOAD X
+If a wakeup does occur, one (at least) of the two loads must see 1. If, on
+the other hand, a wakeup does not occur, both loads might see 0.
-In contrast, if a wakeup does occur, CPU 2's load from X would be guaranteed
-to see 1.
+wake_up_process() always executes a general memory barrier. The barrier again
+occurs before the task state is accessed. In particular, if the wake_up() in
+the previous snippet were replaced by a call to wake_up_process() then one of
+the two loads would be guaranteed to see 1.
The available waker functions include:
@@ -2224,6 +2233,8 @@ The available waker functions include:
+In terms of memory ordering, these functions all provide the same guarantees of
+a wake_up() (or stronger).
[!] Note that the memory barriers implied by the sleeper and the waker do _not_
order multiple stores before the wake-up with respect to loads of those stored