Linux Netfilter development
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: "Paul E. McKenney" <paulmck@kernel.org>
Cc: netfilter-devel@vger.kernel.org, joelagnelf@nvidia.com,
	josh@joshtriplett.org, boqun@kernel.org, urezki@gmail.com,
	rostedt@goodmis.org, mathieu.desnoyers@efficios.com,
	jiangshanlai@gmail.com, qiang.zhang@linux.dev, fw@strlen.de
Subject: Re: [PATCH nf 1/3] rculist: add list_splice_rcu() for private lists
Date: Wed, 15 Apr 2026 11:43:27 +0200	[thread overview]
Message-ID: <ad9dv-rjSUAxCyDp@chamomile> (raw)
In-Reply-To: <25a270bf-0011-4784-9a32-5a62b64a6200@paulmck-laptop>

Hi Paul,

Thanks for your review.

On Tue, Apr 14, 2026 at 04:35:57PM -0700, Paul E. McKenney wrote:
> On Tue, Apr 14, 2026 at 12:04:15AM +0200, Pablo Neira Ayuso wrote:
> > This patch adds a helper function, list_splice_rcu(), to safely splice
> > a private (non-RCU-protected) list into an RCU-protected list.
> > 
> > The function ensures that only the pointer visible to RCU readers
> > (prev->next) is updated using rcu_assign_pointer(), while the rest of
> > the list manipulations are performed with regular assignments, as the
> > source list is private and not visible to concurrent RCU readers.
> > 
> > This is useful for moving elements from a private list into a global
> > RCU-protected list, ensuring safe publication for RCU readers.
> > Subsystems with some sort of batching mechanism from userspace can
> > benefit from this new function.
> > 
> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Looks plausible and useful.  Please see some comments inline below.

Thanks, see below.

> > ---
> > @I need this to fix a unsafe list_splice() of a private list to an
> > existing RCU-protected list. This is based on an existing idiom in
> > __list_splice_init_rcu().
> > 
> >  include/linux/rculist.h | 35 +++++++++++++++++++++++++++++++++++
> >  1 file changed, 35 insertions(+)
> > 
> > diff --git a/include/linux/rculist.h b/include/linux/rculist.h
> > index 2abba7552605..3c18c3336459 100644
> > --- a/include/linux/rculist.h
> > +++ b/include/linux/rculist.h
> > @@ -261,6 +261,41 @@ static inline void list_replace_rcu(struct list_head *old,
> >  	old->prev = LIST_POISON2;
> >  }
> >  
> > +/**
> > + * __list_splice_rcu - join a non-RCU list into an existing list.
> > + * @list:	the RCU-protected list to splice
> 
> This is actually not RCU-protected, correct?  Sure, its elements
> (aside from the list header) are RCU-protected upon exit from this
> function, but by then they are in the {@prev,@next} list, not in
> this @list.

Correct, I can fix this.

> > + * @prev:	points to the last element of the existing list
> > + * @next:	points to the first element of the existing list
> > + *
> > + * The list pointed to by @prev and @next can be RCU-read traversed
> > + * concurrently with this function.
> 
> Doesn't this last sentence also need to go into the list_splice_rcu()
> function's kernel-doc header?  But please see below.

OK.

> > + */
> > +static inline void __list_splice_rcu(struct list_head *list,
> > +				     struct list_head *prev,
> > +				     struct list_head *next)
> > +{
> > +	struct list_head *first = list->next;
> > +	struct list_head *last = list->prev;
> > +
> > +	last->next = next;
> > +	rcu_assign_pointer(list_next_rcu(prev), first);
> > +	first->prev = prev;
> > +	next->prev = last;
> 
> Although putting these last two after the rcu_assign_pointer() is safe,
> given that RCU readers do not traverse ->prev pointers, it would be
> better to place them before the rcu_assign_pointer() in order to avoid
> false sharing between this code path and any concurrent RCU readers.

I can do that.

> > +}
> > +
> > +/**
> > + * list_splice_rcu - splice a non-RCU list into an RCU-protected list,
> > + *                   designed for stacks.
> > + * @list:	the non RCU-protected list to splice
> > + * @head:	the place in the existing list to splice the first list into
> 
> Please add something about @head being RCU-protected.

Will do.

> > + */
> > +static inline void list_splice_rcu(struct list_head *list,
> > +				   struct list_head *head)
> > +{
> > +	if (!list_empty(list))
> > +		__list_splice_rcu(list, head, head->next);
> > +}
> 
> I don't understand the purpose of having __list_splice_rcu() split out
> from list_splice_rcu().  If you are planning to add more callers of
> __list_splice_rcu(), you can always do the split when you add the first
> such caller.  In the meantime, why the extra code?

I only have a use-case for list_splice_rcu(), so OK, single function
is fine with.

> Yes, we do have __list_splice_init_rcu(), but that is because it is
> called from both list_splice_init_rcu() and list_splice_tail_init_rcu().

Understood.

I will be posting a v2 asap.

Thanks!

> > +
> >  /**
> >   * __list_splice_init_rcu - join an RCU-protected list into an existing list.
> >   * @list:	the RCU-protected list to splice
> > -- 
> > 2.47.3
> > 

      reply	other threads:[~2026-04-15  9:43 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-13 22:04 [PATCH nf 1/3] rculist: add list_splice_rcu() for private lists Pablo Neira Ayuso
2026-04-14 23:35 ` Paul E. McKenney
2026-04-15  9:43   ` Pablo Neira Ayuso [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ad9dv-rjSUAxCyDp@chamomile \
    --to=pablo@netfilter.org \
    --cc=boqun@kernel.org \
    --cc=fw@strlen.de \
    --cc=jiangshanlai@gmail.com \
    --cc=joelagnelf@nvidia.com \
    --cc=josh@joshtriplett.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=qiang.zhang@linux.dev \
    --cc=rostedt@goodmis.org \
    --cc=urezki@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox