All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: netfilter-devel@vger.kernel.org, kadlec@netfilter.org,
	linux-crypto@vger.kernel.org
Subject: Re: [PATCH nf-next v4 01/13] rhashtable: add rhashtable_flush_and_free helper
Date: Wed, 9 Sep 2026 16:45:15 +0200	[thread overview]
Message-ID: <aqFw-_Y4JGRF-0Za@strlen.de> (raw)
In-Reply-To: <aqDdwKMbvd9aErLy@gondor.apana.org.au>

Herbert Xu <herbert@gondor.apana.org.au> wrote:
> Florian Westphal <fw@strlen.de> wrote:
> >
> > +void rhashtable_flush_and_free(struct rhashtable *ht,
> > +                              void (*free_fn)(void *ptr, void *arg),
> > +                              void *arg)
> > +{
> > +       struct bucket_table *tbl, *old_tbl, *last_tbl, *new_tbl;
> > +       struct rhashtable_walker *walker;
> > +       unsigned int i;
> > +
> > +       new_tbl = bucket_table_alloc(ht, rounded_hashtable_size(&ht->p),
> > +                                    GFP_KERNEL);
> > +       if (!new_tbl)
> > +               new_tbl = bucket_table_alloc(ht, ht->p.min_size,
> > +                                            GFP_KERNEL | __GFP_NOFAIL);
> > +
> > +       mutex_lock(&ht->mutex);
> 
> Before starting the work you need to stop all existing rehashes.
> 
> This is where it helps if you impose restrictions on the caller.
> For example, if you could guarantee that no insertions or removals
> occur during the call to rhashtable_flush_and_free (the duration of
> the call does not include the actual freeing, which can occur later),
> then it's much easier since you could just call cancel_work_sync on
> the rehashes.
> 
> If you can't guarantee that, then we'll need some sort of a flag to
> stop the rehashes manually.

Hmm. why?  AFAICS the rehash worker holds ht->mutex, i.e. a rehash
might be pending, but it cannot run in parallel.

We called 'rcu_assign_pointer(ht->tbl, new_tbl);' before unlocking the
mutex, so a pending work (resize or rehash) will only see elements
that have been added right after that point.

Am I misreading anything here?

> > +       /* Splice the new, empty table onto the tail of the live table ... */
> > +       old_tbl = rht_dereference(ht->tbl, ht);
> > +       do {
> > +               last_tbl = rhashtable_last_table(ht, old_tbl);
> > +       } while (rhashtable_rehash_attach(ht, last_tbl, new_tbl));
> 
> This loop is only needed if you impose no restrictions on the caller.

Yes, no restrictions are imposed on the caller, at least thats the idea.

> In fact I think this could become a lot simpler since the two
> tables don't need to mix at all.
> 
> Just add an old_tbl field to struct rhashtable, then move the
> old table into it and directly write the new table to tbl.  That
> way none of the complications from overlapping insertions matter
> anymore.

Hmm. What do you think of this version?

+void rhashtable_flush_and_free(struct rhashtable *ht,
+                              void (*free_fn)(void *ptr, void *arg),
+                              void *arg)
+{
+       struct bucket_table *tbl, *old_tbl, *new_tbl;
+
+       new_tbl = bucket_table_alloc(ht, rounded_hashtable_size(&ht->p),
+                                    GFP_KERNEL);
+       if (!new_tbl)
+               new_tbl = bucket_table_alloc(ht, ht->p.min_size,
+                                            GFP_KERNEL | __GFP_NOFAIL);
+
+       /* Make sure we won't race with rhashtable_rehash_table() */
+       mutex_lock(&ht->mutex);
+       old_tbl = rcu_replace_pointer(ht->tbl, new_tbl, lockdep_rht_mutex_is_held(ht));
+       mutex_unlock(&ht->mutex);
+
+       /* Make sure all other CPUs no longer access the old table */
+       synchronize_rcu();

Rest as before.  This way, we don't need to worry about concurrency,
no readers or writers can reach old_tbl anymore.

I'll give this a try.

  reply	other threads:[~2026-09-09 14:45 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04 18:53 [PATCH nf-next v4 00/13] ipset: replace internal hash table with rhashtable Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 01/13] rhashtable: add rhashtable_flush_and_free helper Florian Westphal
2026-09-04 19:29   ` Florian Westphal
2026-09-08  5:12   ` Herbert Xu
2026-09-08  5:30     ` Florian Westphal
2026-09-08  9:04       ` Herbert Xu
2026-09-08  9:56         ` Florian Westphal
2026-09-08 12:39           ` Herbert Xu
2026-09-08 13:25             ` Florian Westphal
2026-09-09  3:49               ` Herbert Xu
2026-09-09  4:17   ` Herbert Xu
2026-09-09 14:45     ` Florian Westphal [this message]
2026-09-10  9:11       ` Herbert Xu
2026-09-10 10:41         ` Florian Westphal
2026-09-11 11:56           ` Herbert Xu
2026-09-11 12:54             ` Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 02/13] netfilter: ipset: add rhashtable boilerplate stubs Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 03/13] netfilter: ipset: add rhltable " Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 04/13] netfilter: ipset: replace internal hash table with rhashtable Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 05/13] netfilter: ipset: re-add forceadd support Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 06/13] netfilter: ipset: also report mem size for cidr storage to userspace Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 07/13] netfilter: ipset: remove obsolete data_next stubs Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 08/13] netfilter: ipset: remove last region lock usage Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 09/13] netfilter: ipset: remove multi-flag Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 10/13] netfilter: ipset: remove resize completely Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 11/13] netfilter: ipset: remove trivial kvfree wrapper Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 12/13] netfilter: ipset: use plain rcu_read_lock Florian Westphal
2026-09-04 18:53 ` [PATCH nf-next v4 13/13] netfilter: ipset: improve lockdep coverage Florian Westphal

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=aqFw-_Y4JGRF-0Za@strlen.de \
    --to=fw@strlen.de \
    --cc=herbert@gondor.apana.org.au \
    --cc=kadlec@netfilter.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.