[PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem

Qinyun Tan posted 4 patches 2 weeks, 1 day ago
include/linux/memcontrol.h | 15 -------------
mm/huge_memory.c           |  3 ++-
mm/list_lru.c              | 31 ++++++++++++++-------------
mm/memcontrol.c            | 43 +++++++-------------------------------
mm/zswap.c                 |  4 ++--
5 files changed, 29 insertions(+), 67 deletions(-)
[PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Posted by Qinyun Tan 2 weeks, 1 day ago
With cgroup.memory=nokmem, the THP deferred split shrinker and the
zswap shrinker are degraded in two ways.

First, both shrinkers are missing the SHRINKER_NONSLAB flag, so
shrinker_memcg_alloc() demotes them to non-memcg-aware shrinkers:
limit-induced reclaim of a cgroup neither splits its partially
unmapped THPs nor writes back its zswapped pages.  v1 of this series
[1] restored the flag to fix that.

However, as Sashiko's review of v1 pointed out [2], the flag alone
is not enough.  __list_lru_init() also collapses every list_lru into
per-node lists under nokmem, so even with the flag restored, the
objects of all cgroups share one list per node: the per-memcg
shrinker bit is only set for whichever memcg happens to repopulate
the empty list, so pressure in other cgroups may not even trigger
the scan, and when it does, the scan walks everyone's objects.

Before commit fafaeceb89a5 ("mm: switch deferred split shrinker to
list_lru"), THP had fully per-memcg deferred split queues embedded
in struct mem_cgroup, working independently of kmem accounting.
nokmem only opts out of kernel slab accounting; THPs and zswapped
pages are user memory and remain charged to their cgroups, so
per-memcg reclaim is still what these shrinkers want.

This series keeps list_lrus backed by SHRINKER_NONSLAB shrinkers
memcg aware under nokmem:

Patch 1 drops the kmemcg_id copy, which is only assigned when kmem
accounting is enabled, and indexes the list_lru xarray with
mem_cgroup_id() instead, so the index works independently of kmem
accounting.  The list_lru plumbing passes memcg pointers now, and
memcg_online_kmem()/memcg_offline_kmem() are inlined into the css
online/offline hooks.  It also drops the nokmem early return from
the offline path so these lrus are reparented on offline.

Patch 2 keeps a list_lru memcg aware under nokmem when its backing
shrinker is registered SHRINKER_NONSLAB.

Patches 3 and 4 restore/add SHRINKER_NONSLAB on the THP deferred
split shrinker and the zswap shrinker.

The savings of nokmem are preserved: slab-backed lrus (e.g. the
superblock dentry/inode lrus) still fall back to per-node lists, and
the per-memcg lists are only allocated when a memcg actually holds
such objects.

Changes in v3:
 - Index the list_lru xarray with mem_cgroup_id() (the cgroup ID)
   instead of the private memcg ID, whose lifetime only covers
   online groups, and pass memcg pointers through the list_lru
   plumbing; inline memcg_online_kmem()/memcg_offline_kmem() into
   the css online/offline hooks (patch 1, per Johannes's review of
   v2 [3]).
 - Describe in patch 3's changelog why fafaeceb89a5 dropped
   SHRINKER_NONSLAB knowingly, per Johannes's pointer to the
   original discussion [3].
 - Collected review tags: Johannes's Reviewed-by on patches 2-4,
   Nhat's and Yosry's Acked-by on patch 4.

[1] https://lore.kernel.org/lkml/20260904033503.4067283-1-qinyuntan@linux.alibaba.com/
[2] https://sashiko.dev/#/patchset/20260904033503.4067283-1-qinyuntan@linux.alibaba.com
[3] https://lore.kernel.org/lkml/20260907110111.2286932-1-qinyuntan@linux.alibaba.com/

Qinyun Tan (4):
  mm: memcontrol: drop kmemcg_id and use mem_cgroup_id() for list_lru
    indexing
  mm: list_lru: keep per-memcg lists with nokmem for NONSLAB-backed lrus
  mm: thp: restore SHRINKER_NONSLAB on the deferred split shrinker
  mm: zswap: mark the zswap shrinker SHRINKER_NONSLAB

 include/linux/memcontrol.h | 15 -------------
 mm/huge_memory.c           |  3 ++-
 mm/list_lru.c              | 31 ++++++++++++++-------------
 mm/memcontrol.c            | 43 +++++++-------------------------------
 mm/zswap.c                 |  4 ++--
 5 files changed, 29 insertions(+), 67 deletions(-)

-- 
2.43.7
Re: [PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Posted by Andrew Morton 2 days, 14 hours ago
On Thu, 10 Sep 2026 16:07:18 +0800 Qinyun Tan <qinyuntan@linux.alibaba.com> wrote:

> With cgroup.memory=nokmem, the THP deferred split shrinker and the
> zswap shrinker are degraded in two ways.

Obvious question which may have recently been addressed:

Why are we keeping nokmem around?  How useful are its memory savings
and is anyone actually using it?

Clearly it isn't well tested and it increases our testing space (beyond
out testing resources, apparently).

If the right answer here is "kill it" then this patchset is introducing
risk into the main codepaths in order to fix codepaths which shouldn't
be there anyway, yes?
Re: [PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Posted by Michal Koutný 2 days, 3 hours ago
On Tue, Sep 22, 2026 at 06:35:47PM -0700, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 10 Sep 2026 16:07:18 +0800 Qinyun Tan <qinyuntan@linux.alibaba.com> wrote:
> 
> > With cgroup.memory=nokmem, the THP deferred split shrinker and the
> > zswap shrinker are degraded in two ways.
> 
> Obvious question which may have recently been addressed:
> 
> Why are we keeping nokmem around?  How useful are its memory savings
> and is anyone actually using it?

Besides (not so significant) memory savings, there are also runtime
savings (not spending time with accounting of each kernel allocation)
and environmnents where shared (not)accounting of kernel objects is
preferred (as other resources than memory are shared anyways).

The above are IMO justifiable reasons and I know such users.

HTH,
Michal
Re: [PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Posted by Andrew Morton 2 weeks ago
On Thu, 10 Sep 2026 16:07:18 +0800 Qinyun Tan <qinyuntan@linux.alibaba.com> wrote:

> With cgroup.memory=nokmem, the THP deferred split shrinker and the
> zswap shrinker are degraded in two ways.
> 
> First, both shrinkers are missing the SHRINKER_NONSLAB flag, so
> shrinker_memcg_alloc() demotes them to non-memcg-aware shrinkers:
> limit-induced reclaim of a cgroup neither splits its partially
> unmapped THPs nor writes back its zswapped pages.  v1 of this series
> [1] restored the flag to fix that.
> 
> However, as Sashiko's review of v1 pointed out [2], the flag alone
> is not enough.  __list_lru_init() also collapses every list_lru into
> per-node lists under nokmem, so even with the flag restored, the
> objects of all cgroups share one list per node: the per-memcg
> shrinker bit is only set for whichever memcg happens to repopulate
> the empty list, so pressure in other cgroups may not even trigger
> the scan, and when it does, the scan walks everyone's objects.
> 
> Before commit fafaeceb89a5 ("mm: switch deferred split shrinker to
> list_lru"), THP had fully per-memcg deferred split queues embedded
> in struct mem_cgroup, working independently of kmem accounting.
> nokmem only opts out of kernel slab accounting; THPs and zswapped
> pages are user memory and remain charged to their cgroups, so
> per-memcg reclaim is still what these shrinkers want.
> 
> This series keeps list_lrus backed by SHRINKER_NONSLAB shrinkers
> memcg aware under nokmem:

Thanks.

It seems that Sashiko still doesn't understand that memory allocations
in __init code are considered "can't fail".

	https://sashiko.dev/#/patchset/20260910080722.3961351-1-qinyuntan@linux.alibaba.com

otoh, failures in the functiond which hugepage_init() calls might be
caused by things other than ENOMEM so I guess we shouldn't zap all that
cleanup code.

Anyway, that's unrelated to your changes.

I'll save this patchset away for later and shall await reviewer input. 
Please poke me in a week or so if there hasn't been any, Things are
crazy lately.
Re: [PATCH v3 0/4] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Posted by Qinyun Tan 3 days, 6 hours ago

On 9/11/26 6:34 AM, Andrew Morton wrote:
> On Thu, 10 Sep 2026 16:07:18 +0800 Qinyun Tan <qinyuntan@linux.alibaba.com> wrote:
> 
>> With cgroup.memory=nokmem, the THP deferred split shrinker and the
>> zswap shrinker are degraded in two ways.
>>
>> First, both shrinkers are missing the SHRINKER_NONSLAB flag, so
>> shrinker_memcg_alloc() demotes them to non-memcg-aware shrinkers:
>> limit-induced reclaim of a cgroup neither splits its partially
>> unmapped THPs nor writes back its zswapped pages.  v1 of this series
>> [1] restored the flag to fix that.
>>
>> However, as Sashiko's review of v1 pointed out [2], the flag alone
>> is not enough.  __list_lru_init() also collapses every list_lru into
>> per-node lists under nokmem, so even with the flag restored, the
>> objects of all cgroups share one list per node: the per-memcg
>> shrinker bit is only set for whichever memcg happens to repopulate
>> the empty list, so pressure in other cgroups may not even trigger
>> the scan, and when it does, the scan walks everyone's objects.
>>
>> Before commit fafaeceb89a5 ("mm: switch deferred split shrinker to
>> list_lru"), THP had fully per-memcg deferred split queues embedded
>> in struct mem_cgroup, working independently of kmem accounting.
>> nokmem only opts out of kernel slab accounting; THPs and zswapped
>> pages are user memory and remain charged to their cgroups, so
>> per-memcg reclaim is still what these shrinkers want.
>>
>> This series keeps list_lrus backed by SHRINKER_NONSLAB shrinkers
>> memcg aware under nokmem:
> 
> Thanks.
> 
> It seems that Sashiko still doesn't understand that memory allocations
> in __init code are considered "can't fail".
> 
> 	https://sashiko.dev/#/patchset/20260910080722.3961351-1-qinyuntan@linux.alibaba.com
> 
> otoh, failures in the functiond which hugepage_init() calls might be
> caused by things other than ENOMEM so I guess we shouldn't zap all that
> cleanup code.
> 
> Anyway, that's unrelated to your changes.
> 
> I'll save this patchset away for later and shall await reviewer input. 
> Please poke me in a week or so if there hasn't been any, Things are
> crazy lately.

Hi Andrew,
 
Thanks for your time looking into this series. A gentle ping, as you
suggested. Please let me know if anything else is needed from my side.

Thanks,
Qinyun Tan