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:
parent
71cb46ae46
commit
45271064e1
|
@ -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()
|
||||||
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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue