Linux cryptographic layer development
 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: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260904185321.30313-1-fw@strlen.de>
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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox