Re: [REGRESSION] 6.18.14 netfilter/nftables consumes way more memory
From: Pablo Neira Ayuso
Date: Fri Mar 06 2026 - 07:26:18 EST
On Fri, Mar 06, 2026 at 01:22:44PM +0100, Pablo Neira Ayuso wrote:
> Hi Chris,
>
> On Thu, Mar 05, 2026 at 10:28:49AM -0600, Chris Arges wrote:
> > I noticed after I sent, thanks for fixing.
> > > Hi,
> > >
> > > On Wed, Mar 04, 2026 at 11:50:54AM -0600, Chris Arges wrote:
> > > > Hello,
> > > >
> > > > We've noticed significant slab unreclaimable memory increase after upgrading
> > > > from 6.18.12 to 6.18.15. Other memory values look fairly close, but in my
> > > > testing slab unreclaimable goes from 1.7 GB to 4.9 GB on machines.
> > >
> > > From where are you collecting these memory consumption numbers?
> > >
> >
> > These numbers come from the cgroup's memory.stat:
> > ```
> > $ cat /sys/fs/cgroup/path/to/service/memory.stat | grep slab
> > slab_reclaimable 35874232
> > slab_unreclaimable 5343553056
> > slab 5379427288
> > ```
> >
> > > > Our use case is having nft rules like below, but adding them to 1000s of
> > > > network namespaces. This is essentially running `nft -f` for all these
> > > > namespaces every minute.
> > >
> > > Those numbers for only 1000? That is too little number of entries for
> > > such increase in memory usage that you report.
> > >
> >
> > For this workload that I suspect (since its in the cgroup) it has the following
> > characteristics:
> > - 1000s of namespaces
> > - 1000s of CIDRs in ip list per namespace
> > - Updating everything frequently (<1m)
>
> I see what is going on, my resize logic is not correct. This is
> increasing the size for each new transaction, then the array is
> getting larger and larger on each transaction update.
>
> Could you please give a try to this patch?
Scratch that.
Please, give a try to this patch.
Thanks.
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 853ff30a208c..cffeb6f5c532 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -646,7 +646,7 @@ static int nft_array_may_resize(const struct nft_set *set)
struct nft_array *array;
if (!priv->array_next) {
- array = nft_array_alloc(nelems + NFT_ARRAY_EXTRA_SIZE);
+ array = nft_array_alloc(priv->array->max_intervals);
if (!array)
return -ENOMEM;