On Sun, Aug 11, 2019 at 06:11:10PM -0400, Joel Fernandes (Google) wrote:
> This patch updates the documentation with information about
> usage of lockdep with list_for_each_entry_rcu().
> 
> Signed-off-by: Joel Fernandes (Google) <j...@joelfernandes.org>

Thank you!!!

I queued this for v5.5 with the following wordsmithing.  Please check
to make sure that I didn't mess anything up.

                                                        Thanx, Paul

------------------------------------------------------------------------

commit d06933df6b5919abfd298291f2a6b0a3a095ae64
Author: Joel Fernandes (Google) <j...@joelfernandes.org>
Date:   Sun Aug 11 18:11:10 2019 -0400

    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) <j...@joelfernandes.org>
    [ paulmck: Wordsmithing. ]
    Signed-off-by: Paul E. McKenney <paul...@linux.ibm.com>

diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt
index da51d3068850..89db949eeca0 100644
--- a/Documentation/RCU/lockdep.txt
+++ b/Documentation/RCU/lockdep.txt
@@ -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
 or the RCU-protected data that it points to can change concurrently.
 
-There are currently only "universal" versions of the rcu_assign_pointer()
-and RCU list-/tree-traversal primitives, which do not (yet) check for
-being in an RCU read-side critical section.  In the future, separate
-versions of these primitives might be created.
+Like rcu_dereference(), when lockdep is enabled, RCU list and hlist
+traversal primitives check for being called from within an RCU read-side
+critical section.  However, a lockdep expression can be passed to them
+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))
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 17f48319ee16..58ba05c4d97f 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -290,7 +290,7 @@ rcu_dereference()
        at any time, including immediately after the rcu_dereference().
        And, again like rcu_assign_pointer(), rcu_dereference() is
        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
        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
        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
 reader, updater, and reclaimer.
 

Reply via email to