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: Joel Fernandes (Google) <joel@joelfernandes.org>
[ paulmck: Wordsmithing. ]
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
Joel Fernandes (Google) 2019-08-11 18:11:10 -04:00 committed by Paul E. McKenney
parent 71cb46ae46
commit 45271064e1
2 changed files with 23 additions and 5 deletions

View File

@ -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))

View File

@ -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()
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.