[PATCH 3/5] list.h: synchronize hlist_for_each_entry* iterators with linux
Stefan Roese
sr at denx.de
Fri Oct 28 16:05:51 CEST 2022
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.levin at 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.villemoes at 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 <sr at denx.de>
Tested-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
More information about the U-Boot
mailing list