On 28.10.22 13:50, Rasmus Villemoes wrote:
All the way back in 2013, the linux kernel updated the four
hlist_for_each_entry* iterators to require one less auxiliary
variable:

   commit b67bfe0d42cac56c512dd5da4b1b347a23f4b70a
   Author: Sasha Levin <sasha.le...@oracle.com>
   Date:   Wed Feb 27 17:06:00 2013 -0800

       hlist: drop the node parameter from iterators

Currently, there is only one "user" of any of these, namely in
fs/ubifs/super.c, but that actually uses the "new-style" form, and
is (obviously, or it wouldn't have built) inside #ifndef __UBOOT__.

Before adding actual users of these, import the version as of linux
v6.1-rc1, including the hlist_entry_safe() helper used by the new
versions.

Signed-off-by: Rasmus Villemoes <rasmus.villem...@prevas.dk>
---
  include/linux/list.h | 53 +++++++++++++++++++++-----------------------
  1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/include/linux/list.h b/include/linux/list.h
index 3eacf68e3a..6910721c00 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -646,54 +646,51 @@ static inline void hlist_add_after(struct hlist_node *n,
        for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
             pos = n)
+#define hlist_entry_safe(ptr, type, member) \
+       ({ typeof(ptr) ____ptr = (ptr); \
+          ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+       })
+
  /**
   * hlist_for_each_entry       - iterate over list of given type
- * @tpos:      the type * to use as a loop cursor.
- * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @pos:       the type * to use as a loop cursor.
   * @head:     the head for your list.
   * @member:   the name of the hlist_node within the struct.
   */
-#define hlist_for_each_entry(tpos, pos, head, member)                   \
-       for (pos = (head)->first;                                     \
-            pos && ({ prefetch(pos->next); 1;}) &&                   \
-               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-            pos = pos->next)
+#define hlist_for_each_entry(pos, head, member)                                
\
+       for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
+            pos;                                                       \
+            pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
/**
   * hlist_for_each_entry_continue - iterate over a hlist continuing after 
current point
- * @tpos:      the type * to use as a loop cursor.
- * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @pos:       the type * to use as a loop cursor.
   * @member:   the name of the hlist_node within the struct.
   */
-#define hlist_for_each_entry_continue(tpos, pos, member)                \
-       for (pos = (pos)->next;                                               \
-            pos && ({ prefetch(pos->next); 1;}) &&                   \
-               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-            pos = pos->next)
+#define hlist_for_each_entry_continue(pos, member)                     \
+       for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), 
member);\
+            pos;                                                       \
+            pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
/**
   * hlist_for_each_entry_from - iterate over a hlist continuing from current 
point
- * @tpos:      the type * to use as a loop cursor.
- * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @pos:       the type * to use as a loop cursor.
   * @member:   the name of the hlist_node within the struct.
   */
-#define hlist_for_each_entry_from(tpos, pos, member)                    \
-       for (; pos && ({ prefetch(pos->next); 1;}) &&                         \
-               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-            pos = pos->next)
+#define hlist_for_each_entry_from(pos, member)                         \
+       for (; pos;                                                     \
+            pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
/**
   * hlist_for_each_entry_safe - iterate over list of given type safe against 
removal of list entry
- * @tpos:      the type * to use as a loop cursor.
- * @pos:       the &struct hlist_node to use as a loop cursor.
- * @n:         another &struct hlist_node to use as temporary storage
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         a &struct hlist_node to use as temporary storage
   * @head:     the head for your list.
   * @member:   the name of the hlist_node within the struct.
   */
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
-       for (pos = (head)->first;                                     \
-            pos && ({ n = pos->next; 1; }) &&                                \
-               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-            pos = n)
+#define hlist_for_each_entry_safe(pos, n, head, member)                \
+       for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
+            pos && ({ n = pos->member.next; 1; });                  \
+            pos = hlist_entry_safe(n, typeof(*pos), member))
#endif

Reviewed-by: Stefan Roese <s...@denx.de>
Tested-by: Stefan Roese <s...@denx.de>

Thanks,
Stefan

Reply via email to