summaryrefslogtreecommitdiffstats
path: root/include/linux/rculist.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/rculist.h')
-rw-r--r--include/linux/rculist.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index e649bd3f2c9..3ba2998b22b 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -383,5 +383,22 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
pos = rcu_dereference(pos->next))
+/**
+ * hlist_for_each_entry_rcu_safenext - iterate over rcu list of given type
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ * @next: the &struct hlist_node to use as a next cursor
+ *
+ * Special version of hlist_for_each_entry_rcu that make sure
+ * each next pointer is fetched before each iteration.
+ */
+#define hlist_for_each_entry_rcu_safenext(tpos, pos, head, member, next) \
+ for (pos = rcu_dereference((head)->first); \
+ pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
+ pos = rcu_dereference(next))
+
#endif /* __KERNEL__ */
#endif