]> git.proxmox.com Git - mirror_ovs.git/commitdiff
compat: rcu: Add support for consolidated-RCU reader checking
authorJoel Fernandes (Google) <joel@joelfernandes.org>
Wed, 21 Oct 2020 16:49:39 +0000 (09:49 -0700)
committerIlya Maximets <i.maximets@ovn.org>
Fri, 27 Nov 2020 13:31:27 +0000 (14:31 +0100)
Upstream commit:
    commit 28875945ba98d1b47a8a706812b6494d165bb0a0
    Author: Joel Fernandes (Google) <joel@joelfernandes.org>
    Date:   Tue Jul 16 18:12:22 2019 -0400

    rcu: Add support for consolidated-RCU reader checking

    This commit adds RCU-reader checks to list_for_each_entry_rcu() and
    hlist_for_each_entry_rcu().  These checks are optional, and are indicated
    by a lockdep expression passed to a new optional argument to these two
    macros.  If this optional lockdep expression is omitted, these two macros
    act as before, checking for an RCU read-side critical section.

Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
    [ paulmck: Update to eliminate return within macro and update comment. ]
Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
Backport portion of upstream commit for hlist_for_each_entry_rcu() macro
so that it can be used in following bug fix.

Cc: Joel Fernandes (Google) <joel@joelfernandes.org>
Signed-off-by: Greg Rose <gvrose8192@gmail.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
datapath/linux/compat/include/linux/rculist.h

index 8df8ad8a2774f674ec62a899bbf72f2e52783a9e..40fd5e1710969eec91bd0bdc3e66774eefb0c5e8 100644 (file)
@@ -9,9 +9,28 @@
 #define hlist_pprev_rcu(node)   (*((struct hlist_node __rcu **)((node)->pprev)))
 #endif
 
+/*
+ * Check during list traversal that we are within an RCU reader
+ */
+
+#define check_arg_count_one(dummy)
+
+#ifdef CONFIG_PROVE_RCU_LIST
+#define __list_check_rcu(dummy, cond, extra...)                                \
+       ({                                                              \
+       check_arg_count_one(extra);                                     \
+       RCU_LOCKDEP_WARN(!cond && !rcu_read_lock_any_held(),            \
+                        "RCU-list traversed in non-reader section!");  \
+        })
+#else
+#define __list_check_rcu(dummy, cond, extra...)                                \
+       ({ check_arg_count_one(extra); })
+#endif
+
 #undef hlist_for_each_entry_rcu
-#define hlist_for_each_entry_rcu(pos, head, member)                    \
-       for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
+#define hlist_for_each_entry_rcu(pos, head, member, cond...)           \
+       for (__list_check_rcu(dummy, ## cond, 0),                       \
+            pos = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)),\
                        typeof(*(pos)), member);                        \
                pos;                                                    \
                pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\