Commit 45271064 authored by Joel Fernandes (Google)'s avatar Joel Fernandes (Google) Committed by Paul E. McKenney

doc: Update list_for_each_entry_rcu() documentation

This commit updates the documentation with information about
usage of lockdep with list_for_each_entry_rcu().
Signed-off-by: default avatarJoel Fernandes (Google) <joel@joelfernandes.org>
[ paulmck: Wordsmithing. ]
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 71cb46ae
...@@ -96,7 +96,17 @@ other flavors of rcu_dereference(). On the other hand, it is illegal ...@@ -96,7 +96,17 @@ other flavors of rcu_dereference(). On the other hand, it is illegal
to use rcu_dereference_protected() if either the RCU-protected pointer to use rcu_dereference_protected() if either the RCU-protected pointer
or the RCU-protected data that it points to can change concurrently. or the RCU-protected data that it points to can change concurrently.
There are currently only "universal" versions of the rcu_assign_pointer() Like rcu_dereference(), when lockdep is enabled, RCU list and hlist
and RCU list-/tree-traversal primitives, which do not (yet) check for traversal primitives check for being called from within an RCU read-side
being in an RCU read-side critical section. In the future, separate critical section. However, a lockdep expression can be passed to them
versions of these primitives might be created. as a additional optional argument. With this lockdep expression, these
traversal primitives will complain only if the lockdep expression is
false and they are called from outside any RCU read-side critical section.
For example, the workqueue for_each_pwq() macro is intended to be used
either within an RCU read-side critical section or with wq->mutex held.
It is thus implemented as follows:
#define for_each_pwq(pwq, wq)
list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node,
lock_is_held(&(wq->mutex).dep_map))
...@@ -290,7 +290,7 @@ rcu_dereference() ...@@ -290,7 +290,7 @@ rcu_dereference()
at any time, including immediately after the rcu_dereference(). at any time, including immediately after the rcu_dereference().
And, again like rcu_assign_pointer(), rcu_dereference() is And, again like rcu_assign_pointer(), rcu_dereference() is
typically used indirectly, via the _rcu list-manipulation typically used indirectly, via the _rcu list-manipulation
primitives, such as list_for_each_entry_rcu(). primitives, such as list_for_each_entry_rcu() [2].
[1] The variant rcu_dereference_protected() can be used outside [1] The variant rcu_dereference_protected() can be used outside
of an RCU read-side critical section as long as the usage is of an RCU read-side critical section as long as the usage is
...@@ -305,6 +305,14 @@ rcu_dereference() ...@@ -305,6 +305,14 @@ rcu_dereference()
a lockdep splat is emitted. See Documentation/RCU/Design/Requirements/Requirements.rst a lockdep splat is emitted. See Documentation/RCU/Design/Requirements/Requirements.rst
and the API's code comments for more details and example usage. and the API's code comments for more details and example usage.
[2] If the list_for_each_entry_rcu() instance might be used by
update-side code as well as by RCU readers, then an additional
lockdep expression can be added to its list of arguments.
For example, given an additional "lock_is_held(&mylock)" argument,
the RCU lockdep code would complain only if this instance was
invoked outside of an RCU read-side critical section and without
the protection of mylock.
The following diagram shows how each API communicates among the The following diagram shows how each API communicates among the
reader, updater, and reclaimer. reader, updater, and reclaimer.
......
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