Commit 264d4f88 authored by Andrea Parri's avatar Andrea Parri Committed by Paul E. McKenney

doc: Update synchronize_rcu() definition in whatisRCU.txt

The synchronize_rcu() definition based on RW-locks in whatisRCU.txt
does not meet the "Memory-Barrier Guarantees" in Requirements.html;
for example, the following SB-like test:

    P0:                      P1:

    WRITE_ONCE(x, 1);        WRITE_ONCE(y, 1);
    synchronize_rcu();       smp_mb();
    r0 = READ_ONCE(y);       r1 = READ_ONCE(x);

should not be allowed to reach the state "r0 = 0 AND r1 = 0", but
the current write_lock()+write_unlock() definition can not ensure
this.  This commit therefore inserts an smp_mb__after_spinlock()
in order to cause this synchronize_rcu() implementation to provide
this memory-barrier guarantee.
Suggested-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: default avatarAndrea Parri <andrea.parri@amarulasolutions.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 67abb96c
...@@ -588,6 +588,7 @@ It is extremely simple: ...@@ -588,6 +588,7 @@ It is extremely simple:
void synchronize_rcu(void) void synchronize_rcu(void)
{ {
write_lock(&rcu_gp_mutex); write_lock(&rcu_gp_mutex);
smp_mb__after_spinlock();
write_unlock(&rcu_gp_mutex); write_unlock(&rcu_gp_mutex);
} }
...@@ -609,12 +610,15 @@ don't forget about them when submitting patches making use of RCU!] ...@@ -609,12 +610,15 @@ don't forget about them when submitting patches making use of RCU!]
The rcu_read_lock() and rcu_read_unlock() primitive read-acquire The rcu_read_lock() and rcu_read_unlock() primitive read-acquire
and release a global reader-writer lock. The synchronize_rcu() and release a global reader-writer lock. The synchronize_rcu()
primitive write-acquires this same lock, then immediately releases primitive write-acquires this same lock, then releases it. This means
it. This means that once synchronize_rcu() exits, all RCU read-side that once synchronize_rcu() exits, all RCU read-side critical sections
critical sections that were in progress before synchronize_rcu() was that were in progress before synchronize_rcu() was called are guaranteed
called are guaranteed to have completed -- there is no way that to have completed -- there is no way that synchronize_rcu() would have
synchronize_rcu() would have been able to write-acquire the lock been able to write-acquire the lock otherwise. The smp_mb__after_spinlock()
otherwise. promotes synchronize_rcu() to a full memory barrier in compliance with
the "Memory-Barrier Guarantees" listed in:
Documentation/RCU/Design/Requirements/Requirements.html.
It is possible to nest rcu_read_lock(), since reader-writer locks may It is possible to nest rcu_read_lock(), since reader-writer locks may
be recursively acquired. Note also that rcu_read_lock() is immune be recursively acquired. Note also that rcu_read_lock() is immune
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment