[PATCH v2 2/4] mm: list_lru: keep per-memcg lists with nokmem for NONSLAB-backed lrus

From: Qinyun Tan

Date: Mon Sep 07 2026 - 07:17:08 EST


With cgroup.memory=nokmem, __list_lru_init() collapses every list_lru
into per-node lists. That is fine for slab objects, which are not
charged per memcg without kmem accounting. But a lru backed by a
SHRINKER_NONSLAB shrinker, e.g. the THP deferred split queue or the
zswap entries, holds user memory, which is charged regardless of
nokmem. Collapsing such an lru loses the per-memcg view of its
objects. Reclaim can no longer target just the cgroup under pressure.

Keep such lrus memcg aware under nokmem when their backing shrinker is
registered SHRINKER_NONSLAB.

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

Fixes: fafaeceb89a5 ("mm: switch deferred split shrinker to list_lru")
Signed-off-by: Qinyun Tan <qinyuntan@xxxxxxxxxxxxxxxxx>
---
mm/list_lru.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mm/list_lru.c b/mm/list_lru.c
index 6fd4e9af84396..e84eff313a683 100644
--- a/mm/list_lru.c
+++ b/mm/list_lru.c
@@ -671,7 +671,9 @@ int __list_lru_init(struct list_lru *lru, bool memcg_aware, struct shrinker *shr
else
lru->shrinker_id = -1;

- if (mem_cgroup_disabled() || mem_cgroup_kmem_disabled())
+ if (mem_cgroup_disabled() ||
+ (mem_cgroup_kmem_disabled() &&
+ (!shrinker || !(shrinker->flags & SHRINKER_NONSLAB))))
memcg_aware = false;
#endif

--
2.43.7