|
@@ -198,6 +198,32 @@ static inline void list_splice_init_rcu(struct list_head *list,
|
|
|
at->prev = last;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * list_entry_rcu - get the struct for this entry
|
|
|
+ * @ptr: the &struct list_head pointer.
|
|
|
+ * @type: the type of the struct this is embedded in.
|
|
|
+ * @member: the name of the list_struct within the struct.
|
|
|
+ *
|
|
|
+ * This primitive may safely run concurrently with the _rcu list-mutation
|
|
|
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
|
|
|
+ */
|
|
|
+#define list_entry_rcu(ptr, type, member) \
|
|
|
+ container_of(rcu_dereference(ptr), type, member)
|
|
|
+
|
|
|
+/**
|
|
|
+ * list_first_entry_rcu - get the first element from a list
|
|
|
+ * @ptr: the list head to take the element from.
|
|
|
+ * @type: the type of the struct this is embedded in.
|
|
|
+ * @member: the name of the list_struct within the struct.
|
|
|
+ *
|
|
|
+ * Note, that list is expected to be not empty.
|
|
|
+ *
|
|
|
+ * This primitive may safely run concurrently with the _rcu list-mutation
|
|
|
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
|
|
|
+ */
|
|
|
+#define list_first_entry_rcu(ptr, type, member) \
|
|
|
+ list_entry_rcu((ptr)->next, type, member)
|
|
|
+
|
|
|
#define __list_for_each_rcu(pos, head) \
|
|
|
for (pos = rcu_dereference((head)->next); \
|
|
|
pos != (head); \
|
|
@@ -214,9 +240,9 @@ static inline void list_splice_init_rcu(struct list_head *list,
|
|
|
* as long as the traversal is guarded by rcu_read_lock().
|
|
|
*/
|
|
|
#define list_for_each_entry_rcu(pos, head, member) \
|
|
|
- for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \
|
|
|
+ for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
|
|
|
prefetch(pos->member.next), &pos->member != (head); \
|
|
|
- pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member))
|
|
|
+ pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
|
|
|
|
|
|
|
|
|
/**
|