From nobody Fri Sep 25 16:51:05 2026 Received: from out30-101.freemail.mail.aliyun.com (out30-101.freemail.mail.aliyun.com [115.124.30.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB302415B9C; Thu, 10 Sep 2026 08:07:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.101 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027658; cv=none; b=RcQj/u+n5/Th7zSsXy6ZZxts7H06CJoN11gtZjvMhb841WFW1qDpyYLy7Ae+QBieGGP4azqlPyCGpuqCttl2l+qA9jSfTuqh0ZPKuowKc8w3RKKf8q1D3sAa1KOPRyrUmVQVTjv+0BmyYyNb4Ab2kAFRvugmyHC+ZQdzt4c9KD0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027658; c=relaxed/simple; bh=//0WLgUNt9fgPs4qemlo+Lz21gAx2Dz3TRBi1MujaHc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pQruTwVin3bWmDk5FjFKsOwtVz1uVHim6Ut+FfGGLqBh5f1EPw1W/jO8TlyadoBeVA5unA+0oNAieJ6zZ3EYA8Z4Ob3hmgzj0O+mgVZ7Wp1+T14J/uI+mOWwwptqgkcJ+SJFJ2UBWV0FbkxXl+tMZyV5Sm7eqrbQbRusrJ5m7cY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=jfG1CgoB; arc=none smtp.client-ip=115.124.30.101 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="jfG1CgoB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1789027648; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=rY9Nu+B7kXe9cwRRfpxa5psElHxdo5w7y5Ja92igZVY=; b=jfG1CgoBb/y375o+WGQZDtpD+6KrBJZ4212FZpYCj2FRZyjs/XKQIOtOTM7BH9TbUE8lMK9dSiwq0z2FnpiKXadNdXl/EeO8sVi66Jn9G9BT+/dYgSao9iXFEzxYLVgqrJN61u2CNLTihwk1R2W+y/guy+BKxZHHsMDYXjGJ4Bc= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R101e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=qinyuntan@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0XAh0I.A_1789027646; Received: from banye.tbsite.net(mailfrom:qinyuntan@linux.alibaba.com fp:SMTPD_---0XAh0I.A_1789027646 cluster:ay36) by smtp.aliyun-inc.com; Thu, 10 Sep 2026 16:07:27 +0800 From: Qinyun Tan To: Andrew Morton Cc: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , =?UTF-8?q?Michal=20Koutn=C3=BD?= , David Hildenbrand , Zi Yan , Baolin Wang , Usama Arif , Dave Chinner , Qi Zheng , Yosry Ahmed , Nhat Pham , Chengming Zhou , Xunlei Pang , cgroups@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Qinyun Tan Subject: [PATCH v3 1/4] mm: memcontrol: drop kmemcg_id and use mem_cgroup_id() for list_lru indexing Date: Thu, 10 Sep 2026 16:07:19 +0800 Message-ID: <20260910080722.3961351-2-qinyuntan@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> References: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" kmemcg_id is a copy of the private memcg ID and serves no purpose other than indexing the per-memcg list_lru xarray. It is assigned when kmem accounting goes online, which never happens with cgroup.memory=3Dnokmem, and the memcgs then all resolve to the per-node lists. The next patch needs the index to work under nokmem as well. Index the lists with mem_cgroup_id(). The cgroup ID is unique per memcg and is only recycled once the cgroup is destroyed, long after offlining has erased the xarray entries, so a recycled ID cannot resurrect a stale entry. The lookup now takes memcg pointers and routes root and NULL to the per-node lists itself. Also drop the nokmem early return from the offline path, so that the reparenting covers lrus that stay memcg aware without kmem accounting. memcg_online_kmem() and memcg_offline_kmem() are each down to a single statement now; inline them into the css online and offline hooks, dropping the root check, as css_offline() is never called for the root and a memcg that failed css_online() cannot have list_lru entries. Signed-off-by: Qinyun Tan --- include/linux/memcontrol.h | 15 ------------- mm/list_lru.c | 27 ++++++++++++------------ mm/memcontrol.c | 43 +++++++------------------------------- 3 files changed, 22 insertions(+), 63 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index fdf4812e1d818..821dc0e32603a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -254,7 +254,6 @@ struct mem_cgroup { #if BITS_PER_LONG < 64 seqlock_t socket_pressure_seqlock; #endif - int kmemcg_id; =20 #ifdef CONFIG_CGROUP_WRITEBACK struct list_head cgwb_list; @@ -1774,15 +1773,6 @@ static inline void memcg_kmem_uncharge_page(struct p= age *page, int order) __memcg_kmem_uncharge_page(page, order); } =20 -/* - * A helper for accessing memcg's kmem_id, used for getting - * corresponding LRU lists. - */ -static inline int memcg_kmem_id(struct mem_cgroup *memcg) -{ - return memcg ? memcg->kmemcg_id : -1; -} - struct mem_cgroup *mem_cgroup_from_virt(void *p); =20 static inline void count_objcg_events(struct obj_cgroup *objcg, @@ -1850,11 +1840,6 @@ static inline bool memcg_kmem_online(void) return false; } =20 -static inline int memcg_kmem_id(struct mem_cgroup *memcg) -{ - return -1; -} - static inline struct mem_cgroup *mem_cgroup_from_virt(void *p) { return NULL; diff --git a/mm/list_lru.c b/mm/list_lru.c index a4522ca93ebcb..9241d17de4388 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -72,10 +72,11 @@ static int lru_shrinker_id(struct list_lru *lru) } =20 static inline struct list_lru_one * -list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx) +list_lru_from_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memc= g) { - if (list_lru_memcg_aware(lru) && idx >=3D 0) { - struct list_lru_memcg *mlru =3D xa_load(&lru->xa, idx); + if (list_lru_memcg_aware(lru) && memcg && !mem_cgroup_is_root(memcg)) { + struct list_lru_memcg *mlru =3D + xa_load(&lru->xa, mem_cgroup_id(memcg)); =20 return mlru ? &mlru->node[nid] : NULL; } @@ -91,7 +92,7 @@ lock_list_lru_of_memcg(struct list_lru *lru, int nid, =20 rcu_read_lock(); again: - l =3D list_lru_from_memcg_idx(lru, nid, memcg_kmem_id(*memcg)); + l =3D list_lru_from_memcg(lru, nid, *memcg); if (likely(l)) { lock_list_lru(l, irq, irq_flags); if (likely(READ_ONCE(l->nr_items) !=3D LONG_MIN)) { @@ -132,7 +133,7 @@ static inline bool list_lru_memcg_aware(struct list_lru= *lru) } =20 static inline struct list_lru_one * -list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx) +list_lru_from_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memc= g) { return &lru->node[nid].lru; } @@ -313,7 +314,7 @@ unsigned long list_lru_count_one(struct list_lru *lru, long count; =20 rcu_read_lock(); - l =3D list_lru_from_memcg_idx(lru, nid, memcg_kmem_id(memcg)); + l =3D list_lru_from_memcg(lru, nid, memcg); count =3D l ? READ_ONCE(l->nr_items) : 0; rcu_read_unlock(); =20 @@ -502,11 +503,10 @@ static void memcg_reparent_list_lru_one(struct list_l= ru *lru, int nid, struct list_lru_one *src, struct mem_cgroup *dst_memcg) { - int dst_idx =3D dst_memcg->kmemcg_id; struct list_lru_one *dst; =20 spin_lock_irq(&src->lock); - dst =3D list_lru_from_memcg_idx(lru, nid, dst_idx); + dst =3D list_lru_from_memcg(lru, nid, dst_memcg); spin_lock_nested(&dst->lock, SINGLE_DEPTH_NESTING); =20 list_splice_init(&src->list, &dst->list); @@ -536,7 +536,7 @@ void memcg_reparent_list_lrus(struct mem_cgroup *memcg,= struct mem_cgroup *paren * allocating a new mlru since CSS_DYING is already set for this * memcg a rcu grace period ago. */ - mlru =3D xa_load(&lru->xa, memcg->kmemcg_id); + mlru =3D xa_load(&lru->xa, mem_cgroup_id(memcg)); if (!mlru) continue; =20 @@ -551,7 +551,7 @@ void memcg_reparent_list_lrus(struct mem_cgroup *memcg,= struct mem_cgroup *paren for_each_node(i) memcg_reparent_list_lru_one(lru, i, &mlru->node[i], parent); =20 - xa_erase_irq(&lru->xa, memcg->kmemcg_id); + xa_erase_irq(&lru->xa, mem_cgroup_id(memcg)); =20 /* * Here all list_lrus corresponding to the cgroup are guaranteed @@ -566,9 +566,10 @@ void memcg_reparent_list_lrus(struct mem_cgroup *memcg= , struct mem_cgroup *paren static inline bool memcg_list_lru_allocated(struct mem_cgroup *memcg, struct list_lru *lru) { - int idx =3D memcg->kmemcg_id; + if (!memcg || mem_cgroup_is_root(memcg)) + return true; =20 - return idx < 0 || xa_load(&lru->xa, idx); + return xa_load(&lru->xa, mem_cgroup_id(memcg)); } =20 static int __memcg_list_lru_alloc(struct mem_cgroup *memcg, @@ -602,7 +603,7 @@ static int __memcg_list_lru_alloc(struct mem_cgroup *me= mcg, if (!mlru) return -ENOMEM; } - xas_set(&xas, pos->kmemcg_id); + xas_set(&xas, mem_cgroup_id(pos)); do { xas_lock_irqsave(&xas, flags); if (!xas_load(&xas) && !css_is_dying(&pos->css)) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7ce50bccf1264..aa010608fbff8 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3771,33 +3771,6 @@ void folio_split_memcg_refs(struct folio *folio, uns= igned old_order, obj_cgroup_get_many(folio_objcg(folio), new_refs); } =20 -static void memcg_online_kmem(struct mem_cgroup *memcg) -{ - if (mem_cgroup_kmem_disabled()) - return; - - if (unlikely(mem_cgroup_is_root(memcg))) - return; - - static_branch_enable(&memcg_kmem_online_key); - - memcg->kmemcg_id =3D memcg->id.id; -} - -static void memcg_offline_kmem(struct mem_cgroup *memcg) -{ - struct mem_cgroup *parent; - - if (mem_cgroup_kmem_disabled()) - return; - - if (unlikely(mem_cgroup_is_root(memcg))) - return; - - parent =3D parent_mem_cgroup(memcg); - memcg_reparent_list_lrus(memcg, parent); -} - #ifdef CONFIG_CGROUP_WRITEBACK =20 #include @@ -4225,7 +4198,6 @@ static struct mem_cgroup *mem_cgroup_alloc(struct mem= _cgroup *parent) seqlock_init(&memcg->socket_pressure_seqlock); #endif memcg1_memcg_init(memcg); - memcg->kmemcg_id =3D -1; #ifdef CONFIG_CGROUP_WRITEBACK INIT_LIST_HEAD(&memcg->cgwb_list); for (i =3D 0; i < MEMCG_CGWB_FRN_CNT; i++) @@ -4299,7 +4271,8 @@ static int mem_cgroup_css_online(struct cgroup_subsys= _state *css) struct obj_cgroup *objcg; int nid; =20 - memcg_online_kmem(memcg); + if (!mem_cgroup_kmem_disabled() && likely(!mem_cgroup_is_root(memcg))) + static_branch_enable(&memcg_kmem_online_key); =20 /* * A memcg must be visible for expand_shrinker_info() @@ -4307,7 +4280,7 @@ static int mem_cgroup_css_online(struct cgroup_subsys= _state *css) * here, when mem_cgroup_iter() can't skip it. */ if (alloc_shrinker_info(memcg)) - goto offline_kmem; + goto reparent_lrus; =20 for_each_node(nid) { objcg =3D obj_cgroup_alloc(); @@ -4364,8 +4337,8 @@ static int mem_cgroup_css_online(struct cgroup_subsys= _state *css) } } free_shrinker_info(memcg); -offline_kmem: - memcg_offline_kmem(memcg); +reparent_lrus: + memcg_reparent_list_lrus(memcg, parent_mem_cgroup(memcg)); mem_cgroup_private_id_remove(memcg); return -ENOMEM; } @@ -4381,11 +4354,11 @@ static void mem_cgroup_css_offline(struct cgroup_su= bsys_state *css) =20 zswap_memcg_offline_cleanup(memcg); =20 - memcg_offline_kmem(memcg); + memcg_reparent_list_lrus(memcg, parent_mem_cgroup(memcg)); /* * The reparenting of objcg must be after the reparenting of - * the list_lru in memcg_offline_kmem(), which ensures that - * they will not mistakenly get the parent list_lru. + * the list_lru above, which ensures that they will not + * mistakenly get the parent list_lru. */ memcg_reparent_objcgs(memcg); reparent_shrinker_deferred(memcg); --=20 2.43.7 From nobody Fri Sep 25 16:51:05 2026 Received: from out30-130.freemail.mail.aliyun.com (out30-130.freemail.mail.aliyun.com [115.124.30.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FA5441612A; Thu, 10 Sep 2026 08:07:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027656; cv=none; b=oV2rv2AK9AxT9wlwtmrLR1J5OahgxRsK/KnhjCrRogsqNycmFpF6zmrtARGmKUixWnq3uq2kvkTPNl6Lkcx3t7LGUSRTZqEo0Pv9V8+Zcyj+N+PiSmCRZ2+CPaXg0yng+oP4ebfwsylg9qtoq9ky+zfzOuLFC3Eo13OPWLX5/uQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027656; c=relaxed/simple; bh=3+vesp5kBdBexjM4Ik/g66EKgcNzW2drl17So5O+UqM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eJtUcdEt66SUI7drp7SXW9NOSS6YqQ/F4kC4SzasTY2ycpLGLXx2AQiefkGo/AsPSl0jXRCGmXz5QEtc8H/TD+kXX1xXS8VNBnttE6CAuitYFP2WiLsr7EoMtMfQG3Ux9YU6bmxI30d5/dvpfWPrq2g6lu3GRABDf4s7cd6yIig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=W7Yh0Rq3; arc=none smtp.client-ip=115.124.30.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="W7Yh0Rq3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1789027650; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=odM12/YIoq0YjT8DIJyO3FoSw5OF0hQ5pi5E6fmeHeU=; b=W7Yh0Rq3QS6NKtwwVN2NGXlqCU72+3oXOrzsrzBpiKmO9S+ToKqrzZzMyWpR+NGw3ehhoHeHpmrn3wg/L9g/icHElEaf4L1UlFxOKvRZIkVfFvd9JAkWDEGvIMGQxU+doB/OKrZrIHlL9CkkwnLq3hBCmWhrihvyjouzsbqYZqw= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R381e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033037009110;MF=qinyuntan@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0XAh0I.Y_1789027647; Received: from banye.tbsite.net(mailfrom:qinyuntan@linux.alibaba.com fp:SMTPD_---0XAh0I.Y_1789027647 cluster:ay36) by smtp.aliyun-inc.com; Thu, 10 Sep 2026 16:07:28 +0800 From: Qinyun Tan To: Andrew Morton Cc: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , =?UTF-8?q?Michal=20Koutn=C3=BD?= , David Hildenbrand , Zi Yan , Baolin Wang , Usama Arif , Dave Chinner , Qi Zheng , Yosry Ahmed , Nhat Pham , Chengming Zhou , Xunlei Pang , cgroups@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Qinyun Tan Subject: [PATCH v3 2/4] mm: list_lru: keep per-memcg lists with nokmem for NONSLAB-backed lrus Date: Thu, 10 Sep 2026 16:07:20 +0800 Message-ID: <20260910080722.3961351-3-qinyuntan@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> References: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With cgroup.memory=3Dnokmem, __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 Reviewed-by: Johannes Weiner --- 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 9241d17de4388..d20faa6de6c02 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -672,7 +672,9 @@ int __list_lru_init(struct list_lru *lru, bool memcg_aw= are, struct shrinker *shr else lru->shrinker_id =3D -1; =20 - if (mem_cgroup_disabled() || mem_cgroup_kmem_disabled()) + if (mem_cgroup_disabled() || + (mem_cgroup_kmem_disabled() && + (!shrinker || !(shrinker->flags & SHRINKER_NONSLAB)))) memcg_aware =3D false; #endif =20 --=20 2.43.7 From nobody Fri Sep 25 16:51:05 2026 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E37EF416844; Thu, 10 Sep 2026 08:07:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027665; cv=none; b=bFDqQnWivpl0Gof3g+M9GyM7NVdU6W7X4GY5ZJmCHAH1WjwlTSJlGK665Oi8955xTqWlqE5p0R8HF2cwWuK4gI520TDpjsi/vrku2sbUZ8lWq3xsaSjVohaG+VRtL3/Ii90XUIO11NaCpW5swSew7YcPI6n2rGNhH/N3UzpXLYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027665; c=relaxed/simple; bh=jeSTD1mKKdfRm+R1M5Tv0FzCuI2z6+Mfhqu3Z7dGfJw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WvRrrF6lgmDARpZ4tfynejTXk4Sp2xJNAFwEA137hOjJOSMFZlEybrKnxhAYmCMPaV/B7vkOwWtM+KZfCBaBXDlrXkgcZagBJIFKMOAHeGOP2ursITjk436XfygmJWFeDQgxD4nVcZ/zl2MB4a+0X/Ei1xKPKRqHOYeZDGBtwNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=hPoj4KHc; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="hPoj4KHc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1789027652; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type; bh=yOGxmv+6Opxbs9N7PyJbTc7/4fbErynFF1JLR/lLM04=; b=hPoj4KHckDJCNCslu2bE5QRV0T20zOJaL+A3JtD6inni7kvCYNv2BzSpv9AyfJ2hLCcBOEtnyNY4GZLv+sfMTkdUEkl4exIagVptCW+83wffsIlF/vk5nTUwGx0ppSm5ER8SERn0rVdRxGsdHblcKXJalRHwBAxQPNY8QIWFcg0= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R471e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045133197;MF=qinyuntan@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0XAh0I06_1789027649; Received: from banye.tbsite.net(mailfrom:qinyuntan@linux.alibaba.com fp:SMTPD_---0XAh0I06_1789027649 cluster:ay36) by smtp.aliyun-inc.com; Thu, 10 Sep 2026 16:07:30 +0800 From: Qinyun Tan To: Andrew Morton Cc: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , =?UTF-8?q?Michal=20Koutn=C3=BD?= , David Hildenbrand , Zi Yan , Baolin Wang , Usama Arif , Dave Chinner , Qi Zheng , Yosry Ahmed , Nhat Pham , Chengming Zhou , Xunlei Pang , cgroups@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Qinyun Tan Subject: [PATCH v3 3/4] mm: thp: restore SHRINKER_NONSLAB on the deferred split shrinker Date: Thu, 10 Sep 2026 16:07:21 +0800 Message-ID: <20260910080722.3961351-4-qinyuntan@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> References: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable On a system booted with cgroup.memory=3Dnokmem, the deferred split shrinker is demoted to a non-memcg-aware one. As a result, partially unmapped THPs are only split under global reclaim; memcg (limit-induced) reclaim never splits them, so a cgroup under memory pressure keeps its underused THPs intact. The shrinker has carried SHRINKER_NONSLAB since commit 0a432dcbeb32 ("mm: shrinker: make shrinker not depend on memcg kmem") precisely so it would keep working with kmem accounting disabled. Commit fafaeceb89a5 ("mm: switch deferred split shrinker to list_lru") dropped it knowingly: under nokmem the list_lru collapses into a shared per-node list while __list_lru_add() still sets the shrinker bit on whichever memcg happens to add the first item, and with the flag set the shrinker would run twice per reclaim cycle [1]. NONSLAB-backed lrus keep their per-memcg lists under nokmem now, so the shrinker bit identifies the owning memcg again. Restore the flag. This was noticed by Michal during review of the patch "mm/list_lru: don't copy stale shrinker id from non-memcg-aware shrinkers" [2]. [1] https://lore.kernel.org/all/ah9PGv12mqai84ES@cmpxchg.org/ [2] https://lore.kernel.org/lkml/697713c4-0857-485b-aba7-c74f37a3c8b4@linux= .alibaba.com/ Fixes: fafaeceb89a5 ("mm: switch deferred split shrinker to list_lru") Suggested-by: Michal Koutn=C3=BD Signed-off-by: Qinyun Tan Acked-by: Zi Yan Acked-by: David Hildenbrand (Arm) Acked-by: Usama Arif Reviewed-by: Baolin Wang Reviewed-by: Johannes Weiner --- mm/huge_memory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index c5d11147b69ae..87c9fc48b7cfd 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1064,7 +1064,8 @@ int folio_memcg_alloc_deferred(struct folio *folio) static int __init thp_shrinker_init(void) { deferred_split_shrinker =3D shrinker_alloc(SHRINKER_NUMA_AWARE | - SHRINKER_MEMCG_AWARE, + SHRINKER_MEMCG_AWARE | + SHRINKER_NONSLAB, "thp-deferred_split"); if (!deferred_split_shrinker) return -ENOMEM; --=20 2.43.7 From nobody Fri Sep 25 16:51:05 2026 Received: from out30-133.freemail.mail.aliyun.com (out30-133.freemail.mail.aliyun.com [115.124.30.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F97C41A554; Thu, 10 Sep 2026 08:07:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027666; cv=none; b=MARSYjbcmFAfpz/NEHnH1yObjUyceTVic04dZZJryG0j6vU0HDPllILMSOwNbF71uWwiXhPWJTgFTjT/hqGN3l4aRt5+PtSBQXfqcHflSM7uYIVCYKukxFWO6VK/6+G17AdJP/lWS/FUferCqi5CpxlJQ09EwN2yCy4drzy75C4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789027666; c=relaxed/simple; bh=PuSI1qMq0DkcA1pXdW8foc0nMUfaG8CDbFHMYMcCW7k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PfKehhjc0MW0Svfsy0U4AOVjHdymw5jDBfCg25HROtwuz5GS9ffm1b+IF8SninAdzhoQSWpcmEEcZ8I9U+egU1sCvXXB5d6Xvffxl41t8PZMHscZKtBTMkcEY5oWoVlPLZvtSFU3p29rbH/WSRTgDDRQAcCOSJUPpEA5Km14cl0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=iPp3nERX; arc=none smtp.client-ip=115.124.30.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="iPp3nERX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1789027653; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type; bh=Uyyb8xZC5wN0Yx0Er0duq/EDpS5BsE842DJqq649HBw=; b=iPp3nERX9cLS1njNxvX5uHMrgxBosGt9Le04l9QQ4lYq+MGpCOXUc0AoCpQleJY8ewANnMCuqpYVOHVtW+RlYal2PX2DJS5yY3tlGK84q6LaZwOdXG8WSk+ZzpoehVr7M/AKmUhyiyzOW5c+7J3tpxBc7yCMW0dUiE85T7CY2HQ= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R131e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=qinyuntan@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0XAh0I0b_1789027650; Received: from banye.tbsite.net(mailfrom:qinyuntan@linux.alibaba.com fp:SMTPD_---0XAh0I0b_1789027650 cluster:ay36) by smtp.aliyun-inc.com; Thu, 10 Sep 2026 16:07:32 +0800 From: Qinyun Tan To: Andrew Morton Cc: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , =?UTF-8?q?Michal=20Koutn=C3=BD?= , David Hildenbrand , Zi Yan , Baolin Wang , Usama Arif , Dave Chinner , Qi Zheng , Yosry Ahmed , Nhat Pham , Chengming Zhou , Xunlei Pang , cgroups@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Qinyun Tan Subject: [PATCH v3 4/4] mm: zswap: mark the zswap shrinker SHRINKER_NONSLAB Date: Thu, 10 Sep 2026 16:07:22 +0800 Message-ID: <20260910080722.3961351-5-qinyuntan@linux.alibaba.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> References: <20260910080722.3961351-1-qinyuntan@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable With kmem accounting disabled (cgroup.memory=3Dnokmem), memcg reclaim never invokes the zswap shrinker: a cgroup under memory pressure does not write back its own zswapped pages to make room; they are only written back by global reclaim or once the global pool limit kicks in. The zswap shrinker is registered memcg-aware but without SHRINKER_NONSLAB, so under nokmem it is treated as a slab shrinker: before commit 03375203e1da ("mm: do not allocate shrinker info with cgroup.memory=3Dnokmem") it was skipped by the !memcg_kmem_online() check in shrink_slab_memcg(); since that commit it is demoted to non-memcg-aware at registration. But the zswap shrinker is not a slab shrinker: it tracks zswap entries and resolves the owning memcg from the folio's objcg, independent of kmem accounting. This was noticed by Michal during review of the patch "mm/list_lru: don't copy stale shrinker id from non-memcg-aware shrinkers" [1]. Mark it SHRINKER_NONSLAB so it keeps its memcg awareness and runs under memcg reclaim with nokmem. [1] https://lore.kernel.org/lkml/697713c4-0857-485b-aba7-c74f37a3c8b4@linux= .alibaba.com/ Fixes: b5ba474f3f51 ("zswap: shrink zswap pool based on memory pressure") Suggested-by: Michal Koutn=C3=BD Signed-off-by: Qinyun Tan Acked-by: Usama Arif Acked-by: Nhat Pham Acked-by: Yosry Ahmed Reviewed-by: Johannes Weiner --- mm/zswap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/zswap.c b/mm/zswap.c index f3ae3c81e48ea..032136942c172 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -1252,8 +1252,8 @@ static struct shrinker *zswap_alloc_shrinker(void) { struct shrinker *shrinker; =20 - shrinker =3D - shrinker_alloc(SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE, "mm-zswap"); + shrinker =3D shrinker_alloc(SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE | + SHRINKER_NONSLAB, "mm-zswap"); if (!shrinker) return NULL; =20 --=20 2.43.7