On Mon, Oct 12, 2026 at 10:54:43PM +0200, Max Kellermann wrote:
> Move some code from hlist_nulls_add_tail_rcu() to the new function
> hlist_nulls_add_behind_rcu() for callers that already know the last
> node of an `hlist_nulls` list, to allow constant-time appends.
> 
> Signed-off-by: Max Kellermann <[email protected]>

I am assuming that this commit should take the same path as the rest
of them.  So:

Reviewed-by: Paul E. McKenney <[email protected]>

> ---
>  include/linux/rculist_nulls.h | 36 +++++++++++++++++++++++++++++------
>  1 file changed, 30 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
> index a97c3bcb1656..054e477dd093 100644
> --- a/include/linux/rculist_nulls.h
> +++ b/include/linux/rculist_nulls.h
> @@ -115,6 +115,33 @@ static inline void hlist_nulls_add_head_rcu(struct 
> hlist_nulls_node *n,
>               WRITE_ONCE(first->pprev, &n->next);
>  }
>  
> +/**
> + * hlist_nulls_add_behind_rcu - append after the last list entry
> + * @n: the new element to add to the hash list.
> + * @last: the last element in the list.
> + *
> + * Adds the specified element after @last while permitting racing RCU
> + * traversals.  @last must be the last list entry, with its next
> + * pointer holding the terminating nulls marker.
> + *
> + * The caller must take whatever precautions are necessary
> + * (such as holding appropriate locks) to avoid racing
> + * with another list-mutation primitive, such as hlist_nulls_add_head_rcu()
> + * or hlist_nulls_del_rcu(), running on this same list.
> + * However, it is perfectly legal to run concurrently with
> + * the _rcu list-traversal primitives, such as
> + * hlist_nulls_for_each_entry_rcu(), used to prevent memory-consistency
> + * problems on Alpha CPUs.  Regardless of the type of CPU, the
> + * list-traversal primitive must be guarded by rcu_read_lock().
> + */
> +static inline void hlist_nulls_add_behind_rcu(struct hlist_nulls_node *n,
> +                                           struct hlist_nulls_node *last)
> +{
> +     WRITE_ONCE(n->next, last->next);
> +     WRITE_ONCE(n->pprev, &last->next);
> +     rcu_assign_pointer(hlist_nulls_next_rcu(last), n);
> +}
> +
>  /**
>   * hlist_nulls_add_tail_rcu
>   * @n: the element to add to the hash list.
> @@ -143,13 +170,10 @@ static inline void hlist_nulls_add_tail_rcu(struct 
> hlist_nulls_node *n,
>       for (i = h->first; !is_a_nulls(i); i = i->next)
>               last = i;
>  
> -     if (last) {
> -             WRITE_ONCE(n->next, last->next);
> -             WRITE_ONCE(n->pprev, &last->next);
> -             rcu_assign_pointer(hlist_nulls_next_rcu(last), n);
> -     } else {
> +     if (last)
> +             hlist_nulls_add_behind_rcu(n, last);
> +     else
>               hlist_nulls_add_head_rcu(n, h);
> -     }
>  }
>  
>  /* after that hlist_nulls_del will work */
> -- 
> 2.47.3
> 
> 

Reply via email to