linux/kernel/rcu
Paul E. McKenney dafc4d1603 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 <joel@joelfernandes.org>
Reported-by: Boqun Feng <boqun.feng@gmail.com>
Reported-by: Frederic Weisbecker <frederic@kernel.org>
Reported-by: Neeraj Upadhyay <quic_neeraju@quicinc.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2023-01-03 17:49:23 -08:00
..
Kconfig printk changes for 6.2 2022-12-12 09:01:36 -08:00
Kconfig.debug rcu: Make SRCU mandatory 2022-11-29 15:00:06 -08:00
Makefile
rcu_segcblist.c
rcu_segcblist.h
rcu.h printk changes for 6.2 2022-12-12 09:01:36 -08:00
rcuscale.c rcu/rcuscale: Use call_rcu_hurry() for async reader test 2022-11-29 14:04:33 -08:00
rcutorture.c Merge branches 'doc.2022.10.20a', 'fixes.2022.10.21a', 'lazy.2022.11.30a', 'srcunmisafe.2022.11.09a', 'torture.2022.10.18c' and 'torturescript.2022.10.20a' into HEAD 2022-11-30 13:20:05 -08:00
refscale.c refscale: Convert test_lock spinlock to raw_spinlock 2022-06-21 15:57:04 -07:00
srcutiny.c srcu: Make Tiny synchronize_srcu() check for readers 2022-12-01 15:49:12 -08:00
srcutree.c srcu: Update comment after the index flip 2023-01-03 17:49:23 -08:00
sync.c rcu/sync: Use call_rcu_hurry() instead of call_rcu 2022-11-29 14:04:33 -08:00
tasks.h Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
tiny.c rcu: Make call_rcu() lazy to save power 2022-11-29 14:02:23 -08:00
tree_exp.h rcu: Make call_rcu() lazy to save power 2022-11-29 14:02:23 -08:00
tree_nocb.h rcu: Shrinker for lazy rcu 2022-11-29 14:02:52 -08:00
tree_plugin.h rcu: Synchronize ->qsmaskinitnext in rcu_boost_kthread_setaffinity() 2022-10-18 14:59:57 -07:00
tree_stall.h sched/debug: Try trigger_single_cpu_backtrace(cpu) in dump_cpu_task() 2022-08-31 05:03:14 -07:00
tree.c Urgent RCU pull request for v6.2 2022-12-21 07:59:57 -08:00
tree.h rcu: Make call_rcu() lazy to save power 2022-11-29 14:02:23 -08:00
update.c rcu: Add test code for semaphore-like SRCU readers 2023-01-03 17:49:22 -08:00