helper/list.h: align file to Linux v5.12
authorAntonio Borneo <borneo.antonio@gmail.com>
Wed, 26 May 2021 12:48:10 +0000 (14:48 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Fri, 4 Jun 2021 16:41:32 +0000 (17:41 +0100)
Main improvement is in the doxygen comments.
Minimize the delta with kernel file.
Skip the functions hlist_unhashed_lockless() and
__list_del_clearprev() that are relevant only in kernel.
Remove gcc extension "omitted conditional operand".

Change-Id: I2e9ddb54cfe2fa5f7cf18f44726acd144e1f98b9
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/6276
Reviewed-by: <rdiezmail-openocd@yahoo.de>
Tested-by: jenkins
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
src/helper/list.h

index 7f6046441d729145d4bfbdef237eb82601c78817..0949636b918372734f11222bcb0d991532ed19d9 100644 (file)
@@ -1,26 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * The content of this file is mainly copied/inspired from Linux kernel
+ * code in include/linux/list.h, include/linux/types.h
+ * Last aligned with kernel v5.12:
+ * - skip the functions hlist_unhashed_lockless() and __list_del_clearprev()
+ *   that are relevant only in kernel;
+ * - Remove non-standard GCC extension "omitted conditional operand" from
+ *   list_prepare_entry;
+ * - expand READ_ONCE, WRITE_ONCE, smp_load_acquire, smp_store_release;
+ * - make comments compatible with doxygen.
+ */
+
 #ifndef OPENOCD_HELPER_LIST_H
 #define OPENOCD_HELPER_LIST_H
 
 /* begin local changes */
 #include <helper/types.h>
 
-#define prefetch(x) ((void)x)
 #define LIST_POISON1 NULL
 #define LIST_POISON2 NULL
 
 struct list_head {
        struct list_head *next, *prev;
 };
+
 struct hlist_head {
        struct hlist_node *first;
 };
+
 struct hlist_node {
        struct hlist_node *next, **pprev;
 };
 /* end local changes */
 
 /*
- * Simple doubly linked list implementation.
+ * Circular doubly linked list implementation.
  *
  * Some of the internal functions ("__xxx") are useful when
  * manipulating whole lists rather than single entries, as
@@ -31,36 +46,58 @@ struct hlist_node {
 
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
-#define LIST_HEAD(name)        \
+#define LIST_HEAD(name) \
        struct list_head name = LIST_HEAD_INIT(name)
 
+/**
+ * INIT_LIST_HEAD - Initialize a list_head structure
+ * @param list list_head structure to be initialized.
+ *
+ * Initializes the list_head to point to itself.  If it is a list header,
+ * the result is an empty list.
+ */
 static inline void INIT_LIST_HEAD(struct list_head *list)
 {
        list->next = list;
        list->prev = list;
 }
 
+#ifdef CONFIG_DEBUG_LIST
+extern bool __list_add_valid(struct list_head *new,
+                             struct list_head *prev,
+                             struct list_head *next);
+extern bool __list_del_entry_valid(struct list_head *entry);
+#else
+static inline bool __list_add_valid(struct list_head *new,
+                               struct list_head *prev,
+                               struct list_head *next)
+{
+       return true;
+}
+static inline bool __list_del_entry_valid(struct list_head *entry)
+{
+       return true;
+}
+#endif
+
 /*
  * Insert a new entry between two known consecutive entries.
  *
  * This is only for internal list manipulation where we know
  * the prev/next entries already!
  */
-#ifndef CONFIG_DEBUG_LIST
 static inline void __list_add(struct list_head *new,
-       struct list_head *prev,
-       struct list_head *next)
+                             struct list_head *prev,
+                             struct list_head *next)
 {
+       if (!__list_add_valid(new, prev, next))
+               return;
+
        next->prev = new;
        new->next = next;
        new->prev = prev;
        prev->next = new;
 }
-#else
-extern void __list_add(struct list_head *new,
-                      struct list_head *prev,
-                      struct list_head *next);
-#endif
 
 /**
  * list_add - add a new entry
@@ -102,28 +139,28 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
        prev->next = next;
 }
 
+/* Ignore kernel __list_del_clearprev() */
+
+static inline void __list_del_entry(struct list_head *entry)
+{
+       if (!__list_del_entry_valid(entry))
+               return;
+
+       __list_del(entry->prev, entry->next);
+}
+
 /**
  * list_del - deletes entry from list.
  * @param entry the element to delete from the list.
  * Note: list_empty() on entry does not return true after this, the entry is
  * in an undefined state.
  */
-#ifndef CONFIG_DEBUG_LIST
-static inline void __list_del_entry(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-}
-
 static inline void list_del(struct list_head *entry)
 {
-       __list_del(entry->prev, entry->next);
+       __list_del_entry(entry);
        entry->next = LIST_POISON1;
        entry->prev = LIST_POISON2;
 }
-#else
-extern void __list_del_entry(struct list_head *entry);
-extern void list_del(struct list_head *entry);
-#endif
 
 /**
  * list_replace - replace old entry by new one
@@ -133,7 +170,7 @@ extern void list_del(struct list_head *entry);
  * If @a old was empty, it will be overwritten.
  */
 static inline void list_replace(struct list_head *old,
-       struct list_head *new)
+                               struct list_head *new)
 {
        new->next = old->next;
        new->next->prev = new;
@@ -141,13 +178,37 @@ static inline void list_replace(struct list_head *old,
        new->prev->next = new;
 }
 
+/**
+ * list_replace_init - replace old entry by new one and initialize the old one
+ * @param old the element to be replaced
+ * @param new the new element to insert
+ *
+ * If @a old was empty, it will be overwritten.
+ */
 static inline void list_replace_init(struct list_head *old,
-       struct list_head *new)
+                                    struct list_head *new)
 {
        list_replace(old, new);
        INIT_LIST_HEAD(old);
 }
 
+/**
+ * list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position
+ * @param entry1 the location to place entry2
+ * @param entry2 the location to place entry1
+ */
+static inline void list_swap(struct list_head *entry1,
+                            struct list_head *entry2)
+{
+       struct list_head *pos = entry2->prev;
+
+       list_del(entry2);
+       list_replace(entry1, entry2);
+       if (pos == entry1)
+               pos = entry2;
+       list_add(entry1, pos);
+}
+
 /**
  * list_del_init - deletes entry from list and reinitialize it.
  * @param entry the element to delete from the list.
@@ -175,19 +236,53 @@ static inline void list_move(struct list_head *list, struct list_head *head)
  * @param head the head that will follow our entry
  */
 static inline void list_move_tail(struct list_head *list,
-       struct list_head *head)
+                                 struct list_head *head)
 {
        __list_del_entry(list);
        list_add_tail(list, head);
 }
 
+/**
+ * list_bulk_move_tail - move a subsection of a list to its tail
+ * @param head  the head that will follow our entry
+ * @param first the first entry to move
+ * @param last  the last entry to move, can be the same as first
+ *
+ * Move all entries between @a first and including @a last before @a head.
+ * All three entries must belong to the same linked list.
+ */
+static inline void list_bulk_move_tail(struct list_head *head,
+                                      struct list_head *first,
+                                      struct list_head *last)
+{
+       first->prev->next = last->next;
+       last->next->prev = first->prev;
+
+       head->prev->next = first;
+       first->prev = head->prev;
+
+       last->next = head;
+       head->prev = last;
+}
+
+/**
+ * list_is_first -- tests whether @a list is the first entry in list @a head
+ * @param list the entry to test
+ * @param head the head of the list
+ */
+static inline int list_is_first(const struct list_head *list,
+                                       const struct list_head *head)
+{
+       return list->prev == head;
+}
+
 /**
  * list_is_last - tests whether @a list is the last entry in list @a head
  * @param list the entry to test
  * @param head the head of the list
  */
 static inline int list_is_last(const struct list_head *list,
-       const struct list_head *head)
+                               const struct list_head *head)
 {
        return list->next == head;
 }
@@ -201,6 +296,24 @@ static inline int list_empty(const struct list_head *head)
        return head->next == head;
 }
 
+/**
+ * list_del_init_careful - deletes entry from list and reinitialize it.
+ * @param entry the element to delete from the list.
+ *
+ * This is the same as list_del_init(), except designed to be used
+ * together with list_empty_careful() in a way to guarantee ordering
+ * of other memory operations.
+ *
+ * Any memory operations done before a list_del_init_careful() are
+ * guaranteed to be visible after a list_empty_careful() test.
+ */
+static inline void list_del_init_careful(struct list_head *entry)
+{
+       __list_del_entry(entry);
+       entry->prev = entry;
+       entry->next = entry;
+}
+
 /**
  * list_empty_careful - tests whether a list is empty and not being modified
  * @param head the list to test
@@ -234,6 +347,24 @@ static inline void list_rotate_left(struct list_head *head)
        }
 }
 
+/**
+ * list_rotate_to_front() - Rotate list to specific item.
+ * @param list The desired new front of the list.
+ * @param head The head of the list.
+ *
+ * Rotates list so that @a list becomes the new front of the list.
+ */
+static inline void list_rotate_to_front(struct list_head *list,
+                                       struct list_head *head)
+{
+       /*
+        * Deletes the list head from the list denoted by @a head and
+        * places it as the tail of @a list, this effectively rotates the
+        * list so that @a list is at the front.
+        */
+       list_move_tail(head, list);
+}
+
 /**
  * list_is_singular - tests whether a list has just one entry.
  * @param head the list to test.
@@ -244,7 +375,7 @@ static inline int list_is_singular(const struct list_head *head)
 }
 
 static inline void __list_cut_position(struct list_head *list,
-       struct list_head *head, struct list_head *entry)
+               struct list_head *head, struct list_head *entry)
 {
        struct list_head *new_first = entry->next;
        list->next = head->next;
@@ -270,12 +401,12 @@ static inline void __list_cut_position(struct list_head *list,
  *
  */
 static inline void list_cut_position(struct list_head *list,
-       struct list_head *head, struct list_head *entry)
+               struct list_head *head, struct list_head *entry)
 {
        if (list_empty(head))
                return;
        if (list_is_singular(head) &&
-           (head->next != entry && head != entry))
+               (head->next != entry && head != entry))
                return;
        if (entry == head)
                INIT_LIST_HEAD(list);
@@ -283,9 +414,39 @@ static inline void list_cut_position(struct list_head *list,
                __list_cut_position(list, head, entry);
 }
 
+/**
+ * list_cut_before - cut a list into two, before given entry
+ * @param list  a new list to add all removed entries
+ * @param head  a list with entries
+ * @param entry an entry within head, could be the head itself
+ *
+ * This helper moves the initial part of @a head, up to but
+ * excluding @a entry, from @a head to @a list.  You should pass
+ * in @a entry an element you know is on @a head.  @a list should
+ * be an empty list or a list you do not care about losing
+ * its data.
+ * If @a entry == @a head, all entries on @a head are moved to
+ * @a list.
+ */
+static inline void list_cut_before(struct list_head *list,
+                                  struct list_head *head,
+                                  struct list_head *entry)
+{
+       if (head->next == entry) {
+               INIT_LIST_HEAD(list);
+               return;
+       }
+       list->next = head->next;
+       list->next->prev = list;
+       list->prev = entry->prev;
+       list->prev->next = list;
+       head->next = entry;
+       entry->prev = head;
+}
+
 static inline void __list_splice(const struct list_head *list,
-       struct list_head *prev,
-       struct list_head *next)
+                                struct list_head *prev,
+                                struct list_head *next)
 {
        struct list_head *first = list->next;
        struct list_head *last = list->prev;
@@ -303,7 +464,7 @@ static inline void __list_splice(const struct list_head *list,
  * @param head the place to add it in the first list.
  */
 static inline void list_splice(const struct list_head *list,
-       struct list_head *head)
+                               struct list_head *head)
 {
        if (!list_empty(list))
                __list_splice(list, head, head->next);
@@ -315,7 +476,7 @@ static inline void list_splice(const struct list_head *list,
  * @param head the place to add it in the first list.
  */
 static inline void list_splice_tail(struct list_head *list,
-       struct list_head *head)
+                               struct list_head *head)
 {
        if (!list_empty(list))
                __list_splice(list, head->prev, head);
@@ -329,7 +490,7 @@ static inline void list_splice_tail(struct list_head *list,
  * The list at @a list is reinitialised
  */
 static inline void list_splice_init(struct list_head *list,
-       struct list_head *head)
+                                   struct list_head *head)
 {
        if (!list_empty(list)) {
                __list_splice(list, head, head->next);
@@ -346,7 +507,7 @@ static inline void list_splice_init(struct list_head *list,
  * The list at @a list is reinitialised
  */
 static inline void list_splice_tail_init(struct list_head *list,
-       struct list_head *head)
+                                        struct list_head *head)
 {
        if (!list_empty(list)) {
                __list_splice(list, head->prev, head);
@@ -358,7 +519,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * list_entry - get the struct for this entry
  * @param ptr    the &struct list_head pointer.
  * @param type   the type of the struct this is embedded in.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  */
 #define list_entry(ptr, type, member) \
        container_of(ptr, type, member)
@@ -367,34 +528,71 @@ static inline void list_splice_tail_init(struct list_head *list,
  * list_first_entry - get the first element from a list
  * @param ptr    the list head to take the element from.
  * @param type   the type of the struct this is embedded in.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Note, that list is expected to be not empty.
  */
 #define list_first_entry(ptr, type, member) \
        list_entry((ptr)->next, type, member)
 
+/**
+ * list_last_entry - get the last element from a list
+ * @param ptr    the list head to take the element from.
+ * @param type   the type of the struct this is embedded in.
+ * @param member the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+       list_entry((ptr)->prev, type, member)
+
+/**
+ * list_first_entry_or_null - get the first element from a list
+ * @param ptr    the list head to take the element from.
+ * @param type   the type of the struct this is embedded in.
+ * @param member the name of the list_head within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) ({ \
+       struct list_head *head__ = (ptr); \
+       struct list_head *pos__ = head__->next; \
+       pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
+})
+
+/**
+ * list_next_entry - get the next element in list
+ * @param pos    the type * to cursor
+ * @param member the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, member) \
+       list_entry((pos)->member.next, typeof(*(pos)), member)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @param pos    the type * to cursor
+ * @param member the name of the list_head within the struct.
+ */
+#define list_prev_entry(pos, member) \
+       list_entry((pos)->member.prev, typeof(*(pos)), member)
+
 /**
  * list_for_each       -       iterate over a list
  * @param pos  the &struct list_head to use as a loop cursor.
  * @param head the head for your list.
  */
 #define list_for_each(pos, head) \
-       for (pos = (head)->next; prefetch(pos->next), pos != (head); \
-            pos = pos->next)
+       for (pos = (head)->next; pos != (head); pos = pos->next)
 
 /**
- * __list_for_each     -       iterate over a list
+ * list_for_each_continue - continue iteration over a list
  * @param pos  the &struct list_head to use as a loop cursor.
  * @param head the head for your list.
  *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
+ * Continue to iterate over a list, continuing after the current position.
  */
-#define __list_for_each(pos, head) \
-       for (pos = (head)->next; pos != (head); pos = pos->next)
+#define list_for_each_continue(pos, head) \
+       for (pos = pos->next; pos != (head); pos = pos->next)
 
 /**
  * list_for_each_prev  -       iterate over a list backwards
@@ -402,8 +600,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @param head the head for your list.
  */
 #define list_for_each_prev(pos, head) \
-       for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
-            pos = pos->prev)
+       for (pos = (head)->prev; pos != (head); pos = pos->prev)
 
 /**
  * list_for_each_safe - iterate over a list safe against removal of list entry
@@ -413,7 +610,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_safe(pos, n, head) \
        for (pos = (head)->next, n = pos->next; pos != (head); \
-            pos = n, n = pos->next)
+               pos = n, n = pos->next)
 
 /**
  * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
@@ -422,148 +619,170 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @param head the head for your list.
  */
 #define list_for_each_prev_safe(pos, n, head) \
-       for (pos = (head)->prev, n = pos->prev; \
-            prefetch(pos->prev), pos != (head); \
+       for (pos = (head)->prev, n = pos->prev; \
+            pos != (head); \
             pos = n, n = pos->prev)
 
+/**
+ * list_entry_is_head - test if the entry points to the head of the list
+ * @param pos    the type * to cursor
+ * @param head   the head for your list.
+ * @param member the name of the list_head within the struct.
+ */
+#define list_entry_is_head(pos, head, member)                          \
+       (&pos->member == (head))
+
 /**
  * list_for_each_entry -       iterate over list of given type
  * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  */
 #define list_for_each_entry(pos, head, member)                         \
-       for (pos = list_entry((head)->next, typeof(*pos), member);      \
-            prefetch(pos->member.next), &pos->member != (head);        \
-            pos = list_entry(pos->member.next, typeof(*pos), member))
+       for (pos = list_first_entry(head, typeof(*pos), member);        \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = list_next_entry(pos, member))
 
 /**
  * list_for_each_entry_reverse - iterate backwards over list of given type.
  * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  */
 #define list_for_each_entry_reverse(pos, head, member)                 \
-       for (pos = list_entry((head)->prev, typeof(*pos), member);      \
-            prefetch(pos->member.prev), &pos->member != (head);        \
-            pos = list_entry(pos->member.prev, typeof(*pos), member))
+       for (pos = list_last_entry(head, typeof(*pos), member);         \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = list_prev_entry(pos, member))
 
 /**
  * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
  * @param pos    the type * to use as a start point
  * @param head   the head of the list
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
  */
 #define list_prepare_entry(pos, head, member) \
-       ((pos) ? : list_entry(head, typeof(*pos), member))
+       ((pos) ? (pos) : list_entry(head, typeof(*pos), member))
 
 /**
  * list_for_each_entry_continue - continue iteration over list of given type
  * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Continue to iterate over list of given type, continuing after
  * the current position.
  */
-#define list_for_each_entry_continue(pos, head, member)                        \
-       for (pos = list_entry(pos->member.next, typeof(*pos), member);  \
-            prefetch(pos->member.next), &pos->member != (head);        \
-            pos = list_entry(pos->member.next, typeof(*pos), member))
+#define list_for_each_entry_continue(pos, head, member)                \
+       for (pos = list_next_entry(pos, member);                        \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = list_next_entry(pos, member))
 
 /**
  * list_for_each_entry_continue_reverse - iterate backwards from the given point
  * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Start to iterate over list of given type backwards, continuing after
  * the current position.
  */
 #define list_for_each_entry_continue_reverse(pos, head, member)                \
-       for (pos = list_entry(pos->member.prev, typeof(*pos), member);  \
-            prefetch(pos->member.prev), &pos->member != (head);        \
-            pos = list_entry(pos->member.prev, typeof(*pos), member))
+       for (pos = list_prev_entry(pos, member);                        \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = list_prev_entry(pos, member))
 
 /**
  * list_for_each_entry_from - iterate over list of given type from the current point
  * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Iterate over list of given type, continuing from current position.
  */
 #define list_for_each_entry_from(pos, head, member)                    \
-       for (; prefetch(pos->member.next), &pos->member != (head);      \
-            pos = list_entry(pos->member.next, typeof(*pos), member))
+       for (; !list_entry_is_head(pos, head, member);                  \
+            pos = list_next_entry(pos, member))
+
+/**
+ * list_for_each_entry_from_reverse - iterate backwards over list of given type
+ *                                    from the current point
+ * @param pos    the type * to use as a loop cursor.
+ * @param head   the head for your list.
+ * @param member the name of the list_head within the struct.
+ *
+ * Iterate backwards over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from_reverse(pos, head, member)            \
+       for (; !list_entry_is_head(pos, head, member);                  \
+            pos = list_prev_entry(pos, member))
 
 /**
  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  * @param pos    the type * to use as a loop cursor.
  * @param n      another type * to use as temporary storage
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  */
 #define list_for_each_entry_safe(pos, n, head, member)                 \
-       for (pos = list_entry((head)->next, typeof(*pos), member),      \
-            n = list_entry(pos->member.next, typeof(*pos), member); \
-            &pos->member != (head);                                    \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+       for (pos = list_first_entry(head, typeof(*pos), member),        \
+               n = list_next_entry(pos, member);                       \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = n, n = list_next_entry(n, member))
 
 /**
  * list_for_each_entry_safe_continue - continue list iteration safe against removal
  * @param pos    the type * to use as a loop cursor.
  * @param n      another type * to use as temporary storage
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * 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_entry(pos->member.next, typeof(*pos), member),          \
-            n = list_entry(pos->member.next, typeof(*pos), member);         \
-            &pos->member != (head);                                            \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#define list_for_each_entry_safe_continue(pos, n, head, member)                \
+       for (pos = list_next_entry(pos, member),                                \
+               n = list_next_entry(pos, member);                               \
+            !list_entry_is_head(pos, head, member);                            \
+            pos = n, n = list_next_entry(n, member))
 
 /**
  * list_for_each_entry_safe_from - iterate over list from current point safe against removal
  * @param pos    the type * to use as a loop cursor.
  * @param n      another type * to use as temporary storage
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * 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_entry(pos->member.next, typeof(*pos), member);            \
-            &pos->member != (head);                                            \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+       for (n = list_next_entry(pos, member);                                  \
+            !list_entry_is_head(pos, head, member);                            \
+            pos = n, n = list_next_entry(n, member))
 
 /**
  * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
  * @param pos    the type * to use as a loop cursor.
  * @param n      another type * to use as temporary storage
  * @param head   the head for your list.
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * Iterate backwards over list of given type, safe against removal
  * of list entry.
  */
 #define list_for_each_entry_safe_reverse(pos, n, head, member)         \
-       for (pos = list_entry((head)->prev, typeof(*pos), member),      \
-            n = list_entry(pos->member.prev, typeof(*pos), member); \
-            &pos->member != (head);                                    \
-            pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+       for (pos = list_last_entry(head, typeof(*pos), member),         \
+               n = list_prev_entry(pos, member);                       \
+            !list_entry_is_head(pos, head, member);                    \
+            pos = n, n = list_prev_entry(n, member))
 
 /**
  * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
  * @param pos    the loop cursor used in the list_for_each_entry_safe loop
  * @param n      temporary storage used in list_for_each_entry_safe
- * @param member the name of the list_struct within the struct.
+ * @param member the name of the list_head within the struct.
  *
  * list_safe_reset_next is not safe to use in general if the list may be
  * modified concurrently (eg. the lock is dropped in the loop body). An
@@ -572,7 +791,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * completing the current iteration of the loop body.
  */
 #define list_safe_reset_next(pos, n, member)                           \
-       n = list_entry(pos->member.next, typeof(*pos), member)
+       n = list_next_entry(pos, member)
 
 /*
  * Double linked lists with a single pointer list head.
@@ -590,11 +809,25 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h)
        h->pprev = NULL;
 }
 
+/**
+ * hlist_unhashed - Has node been removed from list and reinitialized?
+ * @param h Node to be checked
+ *
+ * Not that not all removal functions will leave a node in unhashed
+ * state.  For example, hlist_nulls_del_init_rcu() does leave the
+ * node in unhashed state, but hlist_nulls_del() does not.
+ */
 static inline int hlist_unhashed(const struct hlist_node *h)
 {
        return !h->pprev;
 }
 
+/* Ignore kernel hlist_unhashed_lockless() */
+
+/**
+ * hlist_empty - Is the specified hlist_head structure an empty hlist?
+ * @param h Structure to check.
+ */
 static inline int hlist_empty(const struct hlist_head *h)
 {
        return !h->first;
@@ -604,11 +837,19 @@ static inline void __hlist_del(struct hlist_node *n)
 {
        struct hlist_node *next = n->next;
        struct hlist_node **pprev = n->pprev;
+
        *pprev = next;
        if (next)
                next->pprev = pprev;
 }
 
+/**
+ * hlist_del - Delete the specified hlist_node from its list
+ * @param n Node to delete.
+ *
+ * Note that this function leaves the node in hashed state.  Use
+ * hlist_del_init() or similar instead to unhash @a n.
+ */
 static inline void hlist_del(struct hlist_node *n)
 {
        __hlist_del(n);
@@ -616,6 +857,12 @@ static inline void hlist_del(struct hlist_node *n)
        n->pprev = LIST_POISON2;
 }
 
+/**
+ * hlist_del_init - Delete the specified hlist_node from its list and initialize
+ * @param n Node to delete.
+ *
+ * Note that this function leaves the node in unhashed state.
+ */
 static inline void hlist_del_init(struct hlist_node *n)
 {
        if (!hlist_unhashed(n)) {
@@ -624,6 +871,14 @@ static inline void hlist_del_init(struct hlist_node *n)
        }
 }
 
+/**
+ * hlist_add_head - add a new entry at the beginning of the hlist
+ * @param n new entry to be added
+ * @param h hlist head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
 {
        struct hlist_node *first = h->first;
@@ -634,9 +889,13 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
        n->pprev = &h->first;
 }
 
-/* next must be != NULL */
+/**
+ * hlist_add_before - add a new entry before the one specified
+ * @param n    new entry to be added
+ * @param next hlist node to add it before, which must be non-NULL
+ */
 static inline void hlist_add_before(struct hlist_node *n,
-       struct hlist_node *next)
+                                   struct hlist_node *next)
 {
        n->pprev = next->pprev;
        n->next = next;
@@ -644,29 +903,68 @@ static inline void hlist_add_before(struct hlist_node *n,
        *(n->pprev) = n;
 }
 
-static inline void hlist_add_after(struct hlist_node *n,
-       struct hlist_node *next)
+/**
+ * hlist_add_behind - add a new entry after the one specified
+ * @param n    new entry to be added
+ * @param prev hlist node to add it after, which must be non-NULL
+ */
+static inline void hlist_add_behind(struct hlist_node *n,
+                                   struct hlist_node *prev)
 {
-       next->next = n->next;
-       n->next = next;
-       next->pprev = &n->next;
+       n->next = prev->next;
+       prev->next = n;
+       n->pprev = &prev->next;
 
-       if (next->next)
-               next->next->pprev  = &next->next;
+       if (n->next)
+               n->next->pprev = &n->next;
 }
 
-/* after that we'll appear to be on some hlist and hlist_del will work */
+/**
+ * hlist_add_fake - create a fake hlist consisting of a single headless node
+ * @param n Node to make a fake list out of
+ *
+ * This makes @a n appear to be its own predecessor on a headless hlist.
+ * The point of this is to allow things like hlist_del() to work correctly
+ * in cases where there is no list.
+ */
 static inline void hlist_add_fake(struct hlist_node *n)
 {
        n->pprev = &n->next;
 }
 
-/*
+/**
+ * hlist_fake: Is this node a fake hlist?
+ * @param h Node to check for being a self-referential fake hlist.
+ */
+static inline bool hlist_fake(struct hlist_node *h)
+{
+       return h->pprev == &h->next;
+}
+
+/**
+ * hlist_is_singular_node - is node the only element of the specified hlist?
+ * @param n Node to check for singularity.
+ * @param h Header for potentially singular list.
+ *
+ * Check whether the node is the only node of the head without
+ * accessing head, thus avoiding unnecessary cache misses.
+ */
+static inline bool
+hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
+{
+       return !n->next && n->pprev == &h->first;
+}
+
+/**
+ * hlist_move_list - Move an hlist
+ * @param old hlist_head for old list.
+ * @param new hlist_head for new list.
+ *
  * Move a list from one list head to another. Fixup the pprev
  * reference of the first entry if it exists.
  */
 static inline void hlist_move_list(struct hlist_head *old,
-       struct hlist_head *new)
+                                  struct hlist_head *new)
 {
        new->first = old->first;
        if (new->first)
@@ -677,61 +975,57 @@ static inline void hlist_move_list(struct hlist_head *old,
 #define hlist_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define hlist_for_each(pos, head) \
-       for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
-            pos = pos->next)
+       for (pos = (head)->first; pos ; pos = pos->next)
 
 #define hlist_for_each_safe(pos, n, head) \
        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
- * @param tpos   the type * to use as a loop cursor.
- * @param pos    the &struct hlist_node to use as a loop cursor.
+ * @param pos    the type * to use as a loop cursor.
  * @param head   the head for your list.
  * @param 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
- * @param tpos   the type * to use as a loop cursor.
- * @param pos    the &struct hlist_node to use as a loop cursor.
+ * @param pos    the type * to use as a loop cursor.
  * @param 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
- * @param tpos   the type * to use as a loop cursor.
- * @param pos    the &struct hlist_node to use as a loop cursor.
+ * @param pos    the type * to use as a loop cursor.
  * @param 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
- * @param tpos   the type * to use as a loop cursor.
- * @param pos    the &struct hlist_node to use as a loop cursor.
- * @param n      another &struct hlist_node to use as temporary storage
+ * @param pos    the type * to use as a loop cursor.
+ * @param n      a &struct hlist_node to use as temporary storage
  * @param head   the head for your list.
  * @param 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 /* OPENOCD_HELPER_LIST_H */