From: Qinyun Tan <qinyuntan@linux.alibaba.com>
To: akpm@linux-foundation.org
Cc: hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev,
shakeel.butt@linux.dev, muchun.song@linux.dev, mkoutny@suse.com,
david@kernel.org, ziy@nvidia.com, baolin.wang@linux.alibaba.com,
usama.arif@linux.dev, david@fromorbit.com, qi.zheng@linux.dev,
yosry@kernel.org, nphamcs@gmail.com, chengming.zhou@linux.dev,
xlpang@linux.alibaba.com, ryncsn@gmail.com, gourry@gourry.net,
cgroups@vger.kernel.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org,
Qinyun Tan <qinyuntan@linux.alibaba.com>
Subject: [PATCH v4 0/5] mm: restore per-memcg reclaim for NONSLAB shrinkers under nokmem
Date: Tue, 13 Oct 2026 11:12:16 +0800 [thread overview]
Message-ID: <20261013031221.1997194-1-qinyuntan@linux.alibaba.com> (raw)
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 passes the xarray index directly to the list_lru walker and
drops the reverse memcg lookup that v3 still performed between the
xarray iteration and the walk. That lookup was the cause of the
boot hang reported against v3 [3]: after the keys were switched to
cgroup IDs, the walker kept resolving them as private memcg IDs, so
the global drain kept skipping non-empty per-memcg sublists and
shrink_dcache_sb() could loop forever. Passing the index directly
also removes the temporary css reference from the walk.
Patch 2 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 3 keeps a list_lru memcg aware under nokmem when its backing
shrinker is registered SHRINKER_NONSLAB.
Patches 4 and 5 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 v4:
- Fix the boot hang reported by Kairui against v3 [3]: the walker
no longer reverse-resolves the xarray keys; the index is passed
directly through the internal walk path (new patch 1, split out
as a preparation so patch 2 remains a pure key switch).
- Drop the kmemcg_id member from memcg_struct_check() along with
the field removal, as pointed out by Gregory Price [4].
- Otherwise unchanged from v3.
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 as numbered in v3, per
Johannes's review of v2 [5]).
- Describe in the THP patch's changelog why fafaeceb89a5 dropped
SHRINKER_NONSLAB knowingly, per Johannes's pointer to the
original discussion [5].
- Collected review tags: Johannes's Reviewed-by on patches 2-4,
Nhat's and Yosry's Acked-by on patch 4 (numbering as in v3).
Changes in v2:
- Keep the list_lrus behind the two shrinkers per-memcg under
nokmem, so the shrinker bits are set for the right memcgs and
scans stay scoped to the target cgroup's objects (patches 1-2
as numbered in v2, new; addresses Sashiko's review of v1 [2]).
- Patches 3-4 unchanged from v1; collected the review tags.
[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/20260910080722.3961351-1-qinyuntan@linux.alibaba.com/
[4] https://lore.kernel.org/lkml/arNK64PxTXbVEhis@gourry-fedora-PF4VCD3F/
[5] https://lore.kernel.org/lkml/20260907110111.2286932-1-qinyuntan@linux.alibaba.com/
Qinyun Tan (5):
mm: list_lru: pass the memcg index directly to the walker
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 | 16 ------
mm/huge_memory.c | 3 +-
mm/list_lru.c | 114 +++++++++++++++++++++----------------
mm/memcontrol.c | 45 +++------------
mm/zswap.c | 4 +-
5 files changed, 77 insertions(+), 105 deletions(-)
--
2.43.7
next reply other threads:[~2026-10-13 3:12 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 3:12 Qinyun Tan [this message]
2026-10-13 3:12 ` [PATCH v4 1/5] mm: list_lru: pass the memcg index directly to the walker Qinyun Tan
2026-10-13 3:12 ` [PATCH v4 2/5] mm: memcontrol: drop kmemcg_id and use mem_cgroup_id() for list_lru indexing Qinyun Tan
2026-10-13 3:12 ` [PATCH v4 3/5] mm: list_lru: keep per-memcg lists with nokmem for NONSLAB-backed lrus Qinyun Tan
2026-10-13 3:12 ` [PATCH v4 4/5] mm: thp: restore SHRINKER_NONSLAB on the deferred split shrinker Qinyun Tan
2026-10-13 3:12 ` [PATCH v4 5/5] mm: zswap: mark the zswap shrinker SHRINKER_NONSLAB Qinyun Tan
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=20261013031221.1997194-1-qinyuntan@linux.alibaba.com \
--to=qinyuntan@linux.alibaba.com \
--cc=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=cgroups@vger.kernel.org \
--cc=chengming.zhou@linux.dev \
--cc=david@fromorbit.com \
--cc=david@kernel.org \
--cc=gourry@gourry.net \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@kernel.org \
--cc=mkoutny@suse.com \
--cc=muchun.song@linux.dev \
--cc=nphamcs@gmail.com \
--cc=qi.zheng@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=ryncsn@gmail.com \
--cc=shakeel.butt@linux.dev \
--cc=usama.arif@linux.dev \
--cc=xlpang@linux.alibaba.com \
--cc=yosry@kernel.org \
--cc=ziy@nvidia.com \
/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
all inboxes | Powered by JetHome®