@@ -537,6 +537,17 @@ static inline void list_splice_tail_init
list_entry((pos)->member.next, typeof(*(pos)), member)
/**
+ * list_next_entry_safe - get the next element in list [once]
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ *
+ * Like list_next_entry() but prevents the compiler from reloading the
+ * next element.
+ */
+#define list_next_entry_safe(pos, member) \
+ list_entry(READ_ONCE((pos)->member.next), typeof(*(pos)), member)
+
+/**
* list_prev_entry - get the prev element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
@@ -545,6 +556,17 @@ static inline void list_splice_tail_init
list_entry((pos)->member.prev, typeof(*(pos)), member)
/**
+ * list_prev_entry_safe - get the prev element in list [once]
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ *
+ * Like list_prev_entry() but prevents the compiler from reloading the
+ * previous element.
+ */
+#define list_prev_entry_safe(pos, member) \
+ list_entry(READ_ONCE((pos)->member.prev), typeof(*(pos)), member)
+
+/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
@@ -686,9 +708,9 @@ static inline void list_splice_tail_init
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
- n = list_next_entry(pos, member); \
+ n = list_next_entry_safe(pos, member); \
&pos->member != (head); \
- pos = n, n = list_next_entry(n, member))
+ pos = n, n = list_next_entry_safe(n, member))
/**
* list_for_each_entry_safe_continue - continue list iteration safe against removal
@@ -700,11 +722,11 @@ static inline void list_splice_tail_init
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
*/
-#define list_for_each_entry_safe_continue(pos, n, head, member) \
- for (pos = list_next_entry(pos, member), \
- n = list_next_entry(pos, member); \
- &pos->member != (head); \
- pos = n, n = list_next_entry(n, member))
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_next_entry(pos, member), \
+ n = list_next_entry_safe(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry_safe(n, member))
/**
* list_for_each_entry_safe_from - iterate over list from current point safe against removal
@@ -716,10 +738,10 @@ static inline void list_splice_tail_init
* Iterate over list of given type from current point, safe against
* removal of list entry.
*/
-#define list_for_each_entry_safe_from(pos, n, head, member) \
- for (n = list_next_entry(pos, member); \
- &pos->member != (head); \
- pos = n, n = list_next_entry(n, member))
+#define list_for_each_entry_safe_from(pos, n, head, member) \
+ for (n = list_next_entry_safe(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry_safe(n, member))
/**
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
@@ -733,9 +755,9 @@ static inline void list_splice_tail_init
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member), \
- n = list_prev_entry(pos, member); \
+ n = list_prev_entry_safe(pos, member); \
&pos->member != (head); \
- pos = n, n = list_prev_entry(n, member))
+ pos = n, n = list_prev_entry_safe(n, member))
/**
* list_safe_reset_next - reset a stale list_for_each_entry_safe loop
@@ -750,7 +772,7 @@ static inline void list_splice_tail_init
* completing the current iteration of the loop body.
*/
#define list_safe_reset_next(pos, n, member) \
- n = list_next_entry(pos, member)
+ n = list_next_entry_safe(pos, member)
/*
* Double linked lists with a single pointer list head.