Skip to content

Commit dafc4d1

Browse files
committed
srcu: Update comment after the index flip
Because there is not guaranteed to be a full memory barrier between the ->srcu_unlock_count increment of an srcu_read_unlock() and the ->srcu_lock_count increment of the next srcu_read_lock(), this next srcu_read_lock() is not guaranteed to see the effect of the index flip just prior to this comment. However, this next srcu_read_lock() will execute a full memory barrier, so the srcu_read_lock() after that is guaranteed to see that index flip. This guarantee is illustrated by the following diagram of events and the litmus test following that. ------------------------------------------------------------------------ READER UPDATER ------------- ---------- // idx is initially 0. srcu_flip() { smp_mb(); // RSCS srcu_read_unlock() { smp_mb(); idx++; // P smp_mb(); // QQ } srcu_readers_unlock_idx(0) { ,--counted------------ count all unlock[0]; // Q | unlock[0]++; // X } smp_mb(); srcu_read_lock() { READ(idx) = 0; ,---- count all lock[0]; // contributes imbalance of 1. lock[0]++; ----counted | smp_mb(); // PP } | } | | // RSCS not going to effect above scan | srcu_read_unlock() { | smp_mb(); | unlock[0]++; | } | / / srcu_read_lock() { | READ(idx); // Y -----cannot be counted because of P (has to sample idx as 1) lock[1]++; ... } ------------------------------------------------------------------------ This makes it similar to the store buffer pattern. Using X, Y, P and Q annotated above, we get: ------------------------------------------------------------------------ READER UPDATER X (write) P (write) smp_mb(); //PP smp_mb(); //QQ Y (read) Q (read) ------------------------------------------------------------------------ ASCII art courtesy of Joel Fernandes. Reported-by: Joel Fernandes <[email protected]> Reported-by: Boqun Feng <[email protected]> Reported-by: Frederic Weisbecker <[email protected]> Reported-by: Neeraj Upadhyay <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 0cd4b50 commit dafc4d1

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

kernel/rcu/srcutree.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,10 +1098,11 @@ static void srcu_flip(struct srcu_struct *ssp)
10981098

10991099
/*
11001100
* Ensure that if the updater misses an __srcu_read_unlock()
1101-
* increment, that task's next __srcu_read_lock() will see the
1102-
* above counter update. Note that both this memory barrier
1103-
* and the one in srcu_readers_active_idx_check() provide the
1104-
* guarantee for __srcu_read_lock().
1101+
* increment, that task's __srcu_read_lock() following its next
1102+
* __srcu_read_lock() or __srcu_read_unlock() will see the above
1103+
* counter update. Note that both this memory barrier and the
1104+
* one in srcu_readers_active_idx_check() provide the guarantee
1105+
* for __srcu_read_lock().
11051106
*/
11061107
smp_mb(); /* D */ /* Pairs with C. */
11071108
}

0 commit comments

Comments
 (0)