Commit a3fbf860 authored by Paul E. McKenney's avatar Paul E. McKenney

doc: Clarify rcu_assign_pointer() and rcu_dereference() ordering

This commit expands on the ordering properties of rcu_assign_pointer()
and rcu_dereference(), outlining their constraints on CPUs and compilers.
Reported-by: default avatarRao Shoaib <rao.shoaib@oracle.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 293d9013
...@@ -250,21 +250,25 @@ rcu_assign_pointer() ...@@ -250,21 +250,25 @@ rcu_assign_pointer()
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
void rcu_assign_pointer(p, typeof(p) v); void rcu_assign_pointer(p, typeof(p) v);
Yes, rcu_assign_pointer() **is** implemented as a macro, though it Yes, rcu_assign_pointer() **is** implemented as a macro, though
would be cool to be able to declare a function in this manner. it would be cool to be able to declare a function in this manner.
(Compiler experts will no doubt disagree.) (And there has been some discussion of adding overloaded functions
to the C language, so who knows?)
The updater uses this spatial macro to assign a new value to an The updater uses this spatial macro to assign a new value to an
RCU-protected pointer, in order to safely communicate the change RCU-protected pointer, in order to safely communicate the change
in value from the updater to the reader. This is a spatial (as in value from the updater to the reader. This is a spatial (as
opposed to temporal) macro. It does not evaluate to an rvalue, opposed to temporal) macro. It does not evaluate to an rvalue,
but it does execute any memory-barrier instructions required but it does provide any compiler directives and memory-barrier
for a given CPU architecture. Its ordering properties are that instructions required for a given compile or CPU architecture.
of a store-release operation. Its ordering properties are that of a store-release operation,
that is, any prior loads and stores required to initialize the
Perhaps just as important, it serves to document (1) which structure are ordered before the store that publishes the pointer
pointers are protected by RCU and (2) the point at which a to that structure.
given structure becomes accessible to other CPUs. That said,
Perhaps just as important, rcu_assign_pointer() serves to document
(1) which pointers are protected by RCU and (2) the point at which
a given structure becomes accessible to other CPUs. That said,
rcu_assign_pointer() is most frequently used indirectly, via rcu_assign_pointer() is most frequently used indirectly, via
the _rcu list-manipulation primitives such as list_add_rcu(). the _rcu list-manipulation primitives such as list_add_rcu().
...@@ -283,7 +287,11 @@ rcu_dereference() ...@@ -283,7 +287,11 @@ rcu_dereference()
executes any needed memory-barrier instructions for a given executes any needed memory-barrier instructions for a given
CPU architecture. Currently, only Alpha needs memory barriers CPU architecture. Currently, only Alpha needs memory barriers
within rcu_dereference() -- on other CPUs, it compiles to a within rcu_dereference() -- on other CPUs, it compiles to a
volatile load. volatile load. However, no mainstream C compilers respect
address dependencies, so rcu_dereference() uses volatile casts,
which, in combination with the coding guidelines listed in
rcu_dereference.rst, prevent current compilers from breaking
these dependencies.
Common coding practice uses rcu_dereference() to copy an Common coding practice uses rcu_dereference() to copy an
RCU-protected pointer to a local variable, then dereferences RCU-protected pointer to a local variable, then dereferences
......
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