summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fernandes (Google) <joel@joelfernandes.org>2020-10-21 09:49:39 -0700
committerIlya Maximets <i.maximets@ovn.org>2020-11-27 14:24:51 +0100
commitba3c502e369c12c5fbafc7d247f34eb9437f367c (patch)
tree7de7dbf5053b05e8ada2f43fed3244c9b2c39536
parent7f53ec2230098bf9cc35db9b390aa2322f724b89 (diff)
downloadopenvswitch-ba3c502e369c12c5fbafc7d247f34eb9437f367c.tar.gz
compat: rcu: Add support for consolidated-RCU reader checking
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>
-rw-r--r--datapath/linux/compat/include/linux/rculist.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/datapath/linux/compat/include/linux/rculist.h b/datapath/linux/compat/include/linux/rculist.h
index 8df8ad8a2..40fd5e171 100644
--- a/datapath/linux/compat/include/linux/rculist.h
+++ b/datapath/linux/compat/include/linux/rculist.h
@@ -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(\