[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