Re: [PATCH v2 3/5] mm/mglru: cache the last memcg node, make tail insertion constant time
From: Max Kellermann
Date: Wed Nov 04 2026 - 02:55:50 EST
On Wed, Nov 4, 2026 at 4:40 AM Barry Song <baohua@xxxxxxxxxx> wrote:
>
> On Tue, Nov 3, 2026 at 7:37 PM Max Kellermann <max.kellermann@xxxxxxxxx> wrote:
> >
> > Rotating or onlining a memcg currently uses hlist_nulls_add_tail_rcu()
> > which walks the destination bin to find its tail while holding
> > `memcg_lru.lock` with interrupts disabled. With thousands of cgroups,
> > this takes a long time and causes severe lock contention.
>
> This is the main cause of the soft lockups and RCU stalls,
> right? If so, we may want to add a Fixes tag.
Yes. I added (for v3): Fixes: e4dde56cd208 ("mm: multi-gen LRU:
per-node lru_gen_folio lists")
This commit added lru_gen_rotate_memcg() which calls
hlist_nulls_add_tail_rcu() (full linked list walk under spinlock).
> The fix itself may not be directly applicable to stable
> kernels, but based on the logic of this patch, we should
> be able to work out a backport, right?
The primary copy of these patches lives in our kernel branch that is
based on 6.18 LTS. So I already have a set of patches that can be
backported more easily. Do you want me to submit these versions, too
- and if yes, how?
For me, it is not entirely clear if a stable backport is really
necessary (thus I did not Cc stable). It's not a bug; just awful
performance when you have thousands of memcgs, but few people have
that. But that's up for you to decide.
> Another option is to leave the cleanups in patches 1 and 2
> out for now, and make patch 3 self-contained as the first
> patch in your series, if that makes backporting easier.
I don't think that makes backporting any easier - they are not really
cleanups, but refactoring to make [3/5] as simple&small as possible.
I wouldn't squash them; it improves nothing but makes review harder.
> I'd appreciate it if you could also mention Ridong's earlier
> work in the changelog:
>
> https://lore.kernel.org/all/20251119083722.1365680-1-chenridong@xxxxxxxxxxxxxxx/
Aye.
> > + if (at_head || !last)
> > hlist_nulls_add_head_rcu(&lrugen->list, head);
>
> Do we still need at_head now that MEMCG_LRU_OLD has been removed?
Yes, for the "!last" case. This is, unfortunately, a special case.
If you prefer, we could move this special-casing to the hlist_nulls
API so callers need not be aware of it.
--
Max Kellermann
Principal Architect
Hosting Technology
cm4all | Im Mediapark 6a | 50670 Köln | Germany
General information about the company can be found here:
https://www.cm4all.com/impressum
A member of the IONOS Group