* [PATCH v2 0/2] mm: fix node reclaim swappiness handling
@ 2026-07-16 3:17 Ridong
2026-07-16 3:17 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Ridong
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
0 siblings, 2 replies; 8+ messages in thread
From: Ridong @ 2026-07-16 3:17 UTC (permalink / raw)
To: Johannes Weiner, Michal Hocko, Roman Gushchin, Shakeel Butt,
Andrew Morton, Chris Li, Kairui Song
Cc: Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Youngjun Park, David Hildenbrand, Qi Zheng, Lorenzo Stoakes,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Davidlohr Bueso, cgroups,
linux-mm, linux-kernel, Ridong Chen, Ridong
From: Ridong <chenridong@xiaomi.com>
The per-node proactive reclaim interface
(/sys/devices/system/node/nodeX/reclaim) accepts a swappiness parameter,
but it is silently ignored when CONFIG_MEMCG is disabled. The root cause
is that sc_swappiness() has separate implementations for CONFIG_MEMCG and
!CONFIG_MEMCG, and the latter never checks proactive_swappiness.
Patch 1 moves mem_cgroup_swappiness() and vm_swappiness out of the public
include/linux/swap.h into the mm-private mm/swap.h, and makes the helper
handle both CONFIG_MEMCG and !CONFIG_MEMCG in a single inline function.
This is a prerequisite for unifying sc_swappiness().
Patch 2 consolidates sc_swappiness() into a single definition that works
regardless of CONFIG_MEMCG, fixing the node reclaim swappiness bug.
---
v1 -> v2:
- Move mem_cgroup_swappiness() and vm_swappiness to mm/swap.h instead of
include/linux/memcontrol.h. Suggested by Barry Song.
- Correct fix tag for patch 2.
v1: https://lore.kernel.org/all/20260711091157.306070-1-ridong.chen@linux.dev/
Ridong Chen (2):
memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
mm: vmscan: fix node reclaim ignoring swappiness parameter
include/linux/memcontrol.h | 4 ++--
include/linux/swap.h | 19 -------------------
mm/memcontrol.c | 4 ++--
mm/swap.h | 20 ++++++++++++++++++++
mm/vmscan.c | 19 +++++++------------
5 files changed, 31 insertions(+), 35 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
2026-07-16 3:17 [PATCH v2 0/2] mm: fix node reclaim swappiness handling Ridong
@ 2026-07-16 3:17 ` Ridong
2026-07-16 6:06 ` Tao Cui
2026-07-16 7:14 ` Barry Song
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
1 sibling, 2 replies; 8+ messages in thread
From: Ridong @ 2026-07-16 3:17 UTC (permalink / raw)
To: Johannes Weiner, Michal Hocko, Roman Gushchin, Shakeel Butt,
Andrew Morton, Chris Li, Kairui Song
Cc: Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Youngjun Park, David Hildenbrand, Qi Zheng, Lorenzo Stoakes,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Davidlohr Bueso, cgroups,
linux-mm, linux-kernel, Ridong Chen, Ridong Chen
From: Ridong Chen <chenridong@xiaomi.com>
The per-memcg swappiness knob is v1-only; v2 always uses global
vm_swappiness and ignores the per-cgroup field.
Both mem_cgroup_swappiness() and vm_swappiness are only used within
mm/ (memcontrol.c, memcontrol-v1.c, vmscan.c), so move them out of the
public include/linux/swap.h into the mm-private mm/swap.h. This keeps
unrelated declarations out of include/linux/swap.h.
Guard memcg->swappiness with CONFIG_MEMCG_V1 as well, so v2-only
kernels drop the unused field.
No functional change for v1; v2-only kernels drop the unused field.
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
---
include/linux/memcontrol.h | 4 ++--
include/linux/swap.h | 19 -------------------
mm/memcontrol.c | 4 ++--
mm/swap.h | 20 ++++++++++++++++++++
4 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 957260677678..e7a794dfb40e 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -239,8 +239,6 @@ struct mem_cgroup {
*/
bool oom_group;
- int swappiness;
-
/* memory.events and memory.events.local */
struct cgroup_file events_file;
struct cgroup_file events_local_file;
@@ -318,6 +316,8 @@ struct mem_cgroup {
/* List of events which userspace want to receive */
struct list_head event_list;
spinlock_t event_list_lock;
+
+ int swappiness;
#endif /* CONFIG_MEMCG_V1 */
struct mem_cgroup_per_node *nodeinfo[];
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 696ed01709c2..330a420fd6de 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -309,7 +309,6 @@ static inline bool lru_cache_disabled(void)
}
extern unsigned long shrink_all_memory(unsigned long nr_pages);
-extern int vm_swappiness;
long remove_mapping(struct address_space *mapping, struct folio *folio);
#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
@@ -468,25 +467,7 @@ static inline int add_swap_extent(struct swap_info_struct *sis,
}
#endif /* CONFIG_SWAP */
#ifdef CONFIG_MEMCG
-static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
-{
- /* Cgroup2 doesn't have per-cgroup swappiness */
- if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
- return READ_ONCE(vm_swappiness);
-
- /* root ? */
- if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg))
- return READ_ONCE(vm_swappiness);
-
- return READ_ONCE(memcg->swappiness);
-}
-
void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
-#else
-static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
-{
- return READ_ONCE(vm_swappiness);
-}
#endif
#if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 22f55aeb94f3..d6ba276740ea 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -63,6 +63,7 @@
#include <linux/sched/isolation.h>
#include <linux/kmemleak.h>
#include "internal.h"
+#include "swap.h"
#include "swap_table.h"
#include <net/sock.h>
#include <net/ip.h>
@@ -4174,11 +4175,10 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
#endif
page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);
if (parent) {
- WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
-
page_counter_init(&memcg->memory, &parent->memory, memcg_on_dfl);
page_counter_init(&memcg->swap, &parent->swap, false);
#ifdef CONFIG_MEMCG_V1
+ WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
memcg->memory.track_failcnt = !memcg_on_dfl;
WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
page_counter_init(&memcg->kmem, &parent->kmem, false);
diff --git a/mm/swap.h b/mm/swap.h
index b51ad3071a73..a0e04b97a466 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -4,6 +4,7 @@
#include <linux/atomic.h> /* for atomic_long_t */
#include <linux/mm.h> /* for PAGE_SHIFT */
+#include <linux/memcontrol.h> /* for mem_cgroup_swappiness() */
struct mempolicy;
struct swap_iocb;
struct swap_memcg_table;
@@ -76,6 +77,25 @@ enum swap_cluster_flags {
CLUSTER_FLAG_MAX,
};
+extern int vm_swappiness;
+
+static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
+{
+#ifdef CONFIG_MEMCG_V1
+ /* Cgroup2 doesn't have per-cgroup swappiness */
+ if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
+ return READ_ONCE(vm_swappiness);
+
+ /* root ? */
+ if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg))
+ return READ_ONCE(vm_swappiness);
+
+ return READ_ONCE(memcg->swappiness);
+#else
+ return READ_ONCE(vm_swappiness);
+#endif
+}
+
#ifdef CONFIG_SWAP
#include <linux/swapops.h> /* for swp_offset */
#include <linux/blk_types.h> /* for bio_end_io_t */
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
2026-07-16 3:17 [PATCH v2 0/2] mm: fix node reclaim swappiness handling Ridong
2026-07-16 3:17 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Ridong
@ 2026-07-16 3:17 ` Ridong
2026-07-16 3:25 ` Qi Zheng
` (2 more replies)
1 sibling, 3 replies; 8+ messages in thread
From: Ridong @ 2026-07-16 3:17 UTC (permalink / raw)
To: Johannes Weiner, Michal Hocko, Roman Gushchin, Shakeel Butt,
Andrew Morton, Chris Li, Kairui Song
Cc: Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Youngjun Park, David Hildenbrand, Qi Zheng, Lorenzo Stoakes,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Davidlohr Bueso, cgroups,
linux-mm, linux-kernel, Ridong Chen, Ridong Chen, stable
From: Ridong Chen <chenridong@xiaomi.com>
sc_swappiness() had two separate definitions depending on
CONFIG_MEMCG. The !CONFIG_MEMCG variant simply returned
vm_swappiness, ignoring the proactive_swappiness value passed
through scan_control. This caused the swappiness parameter
written to /sys/devices/system/node/nodeX/reclaim to have no
effect when CONFIG_MEMCG is disabled.
Fix this by consolidating sc_swappiness() into a single definition
that checks sc->proactive_swappiness first, then falls back to
mem_cgroup_swappiness() which already handles both CONFIG_MEMCG
and !CONFIG_MEMCG.
Before fix (swappiness=max ignored, mostly file pages reclaimed):
# cat /proc/sys/vm/swappiness
60
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 1840
pgsteal_anon 25
pgsteal_file 1815
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 18013
pgsteal_anon 337
pgsteal_file 17676
After fix (swappiness=max honored, anon pages reclaimed as expected):
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 0
pgsteal_anon 0
pgsteal_file 0
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 16283
pgsteal_anon 16283
pgsteal_file 0
Cc: stable@vger.kernel.org # 6.17+
Fixes: b980077899ea ("mm: introduce per-node proactive reclaim interface")
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Barry Song <baohua@kernel.org>
---
mm/vmscan.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 986dde8e7429..bd71595c8b2b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -199,6 +199,13 @@ struct scan_control {
*/
int vm_swappiness = 60;
+static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
+{
+ if (sc->proactive && sc->proactive_swappiness)
+ return *sc->proactive_swappiness;
+ return mem_cgroup_swappiness(memcg);
+}
+
#ifdef CONFIG_MEMCG
/* Returns true for reclaim through cgroup limits or cgroup interfaces. */
@@ -239,13 +246,6 @@ static bool writeback_throttling_sane(struct scan_control *sc)
#endif
return false;
}
-
-static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
-{
- if (sc->proactive && sc->proactive_swappiness)
- return *sc->proactive_swappiness;
- return mem_cgroup_swappiness(memcg);
-}
#else
static bool cgroup_reclaim(struct scan_control *sc)
{
@@ -261,11 +261,6 @@ static bool writeback_throttling_sane(struct scan_control *sc)
{
return true;
}
-
-static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
-{
- return READ_ONCE(vm_swappiness);
-}
#endif
static void set_task_reclaim_state(struct task_struct *task,
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
@ 2026-07-16 3:25 ` Qi Zheng
2026-07-16 3:58 ` Qi Zheng
2026-07-16 6:06 ` Tao Cui
2 siblings, 0 replies; 8+ messages in thread
From: Qi Zheng @ 2026-07-16 3:25 UTC (permalink / raw)
To: Ridong, Johannes Weiner, Michal Hocko, Roman Gushchin,
Shakeel Butt, Andrew Morton, Chris Li, Kairui Song
Cc: Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Youngjun Park, David Hildenbrand, Lorenzo Stoakes, Axel Rasmussen,
Yuanchu Xie, Wei Xu, Davidlohr Bueso, cgroups, linux-mm,
linux-kernel, Ridong Chen, stable
On 7/16/26 11:17 AM, Ridong wrote:
> From: Ridong Chen <chenridong@xiaomi.com>
>
> sc_swappiness() had two separate definitions depending on
> CONFIG_MEMCG. The !CONFIG_MEMCG variant simply returned
> vm_swappiness, ignoring the proactive_swappiness value passed
> through scan_control. This caused the swappiness parameter
> written to /sys/devices/system/node/nodeX/reclaim to have no
> effect when CONFIG_MEMCG is disabled.
>
> Fix this by consolidating sc_swappiness() into a single definition
> that checks sc->proactive_swappiness first, then falls back to
> mem_cgroup_swappiness() which already handles both CONFIG_MEMCG
> and !CONFIG_MEMCG.
>
> Before fix (swappiness=max ignored, mostly file pages reclaimed):
>
> # cat /proc/sys/vm/swappiness
> 60
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 1840
> pgsteal_anon 25
> pgsteal_file 1815
> # echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 18013
> pgsteal_anon 337
> pgsteal_file 17676
>
> After fix (swappiness=max honored, anon pages reclaimed as expected):
>
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 0
> pgsteal_anon 0
> pgsteal_file 0
> # echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 16283
> pgsteal_anon 16283
> pgsteal_file 0
>
> Cc: stable@vger.kernel.org # 6.17+
> Fixes: b980077899ea ("mm: introduce per-node proactive reclaim interface")
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
> Reviewed-by: Barry Song <baohua@kernel.org>
> ---
> mm/vmscan.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
Thanks for fixing this!
Acked-by: Qi Zheng <qi.zheng@linux.dev>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
2026-07-16 3:25 ` Qi Zheng
@ 2026-07-16 3:58 ` Qi Zheng
2026-07-16 6:06 ` Tao Cui
2 siblings, 0 replies; 8+ messages in thread
From: Qi Zheng @ 2026-07-16 3:58 UTC (permalink / raw)
To: Ridong, Johannes Weiner, Michal Hocko, Roman Gushchin,
Shakeel Butt, Andrew Morton, Chris Li, Kairui Song
Cc: Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Youngjun Park, David Hildenbrand, Lorenzo Stoakes, Axel Rasmussen,
Yuanchu Xie, Wei Xu, Davidlohr Bueso, cgroups, linux-mm,
linux-kernel, Ridong Chen, stable
Hi Ridong,
On 7/16/26 11:17 AM, Ridong wrote:
> From: Ridong Chen <chenridong@xiaomi.com>
>
> sc_swappiness() had two separate definitions depending on
> CONFIG_MEMCG. The !CONFIG_MEMCG variant simply returned
> vm_swappiness, ignoring the proactive_swappiness value passed
> through scan_control. This caused the swappiness parameter
> written to /sys/devices/system/node/nodeX/reclaim to have no
> effect when CONFIG_MEMCG is disabled.
>
> Fix this by consolidating sc_swappiness() into a single definition
> that checks sc->proactive_swappiness first, then falls back to
> mem_cgroup_swappiness() which already handles both CONFIG_MEMCG
> and !CONFIG_MEMCG.
>
> Before fix (swappiness=max ignored, mostly file pages reclaimed):
>
> # cat /proc/sys/vm/swappiness
> 60
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 1840
> pgsteal_anon 25
> pgsteal_file 1815
> # echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 18013
> pgsteal_anon 337
> pgsteal_file 17676
>
> After fix (swappiness=max honored, anon pages reclaimed as expected):
>
By the way, in get_scan_count(), it seems we still reclaim file pages
without swap space, even if swappiness=max (SWAPPINESS_ANON_ONLY) is
set.
This behavior appears to contradict the semantics of
SWAPPINESS_ANON_ONLY, which probably needs a fix as well.
Thanks,
Qi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
2026-07-16 3:25 ` Qi Zheng
2026-07-16 3:58 ` Qi Zheng
@ 2026-07-16 6:06 ` Tao Cui
2 siblings, 0 replies; 8+ messages in thread
From: Tao Cui @ 2026-07-16 6:06 UTC (permalink / raw)
To: Ridong, Johannes Weiner, Michal Hocko, Roman Gushchin,
Shakeel Butt, Andrew Morton, Chris Li, Kairui Song
Cc: cui.tao, Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He,
Barry Song, Youngjun Park, David Hildenbrand, Qi Zheng,
Lorenzo Stoakes, Axel Rasmussen, Yuanchu Xie, Wei Xu,
Davidlohr Bueso, cgroups, linux-mm, linux-kernel, Ridong Chen,
stable
Hi Ridong,
Reproduced the bug and verified the fix in a QEMU x86_64 guest with
CONFIG_MEMCG disabled. Global vm.swappiness pinned to 1, then:
echo "64M swappiness=<x>" > /sys/devices/system/node/node0/reclaim
swappiness= | buggy (anon/file) | patched (anon/file)
----------- | -------------------- | --------------------
max | 0 / 16385 | 16292 / 0
200 | 2 / 16384 | 16837 / 0
1 | 0 / 16386 | 0 / 16467
Unpatched ignores the swappiness arg (always file); patched honors it.
Matches the commit message.
Tested-by: Song Hu <husong@kylinos.cn>
Reviewed-by: Song Hu <husong@kylinos.cn>
在 2026/7/16 11:17, Ridong 写道:
> From: Ridong Chen <chenridong@xiaomi.com>
>
> sc_swappiness() had two separate definitions depending on
> CONFIG_MEMCG. The !CONFIG_MEMCG variant simply returned
> vm_swappiness, ignoring the proactive_swappiness value passed
> through scan_control. This caused the swappiness parameter
> written to /sys/devices/system/node/nodeX/reclaim to have no
> effect when CONFIG_MEMCG is disabled.
>
> Fix this by consolidating sc_swappiness() into a single definition
> that checks sc->proactive_swappiness first, then falls back to
> mem_cgroup_swappiness() which already handles both CONFIG_MEMCG
> and !CONFIG_MEMCG.
>
> Before fix (swappiness=max ignored, mostly file pages reclaimed):
>
> # cat /proc/sys/vm/swappiness
> 60
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 1840
> pgsteal_anon 25
> pgsteal_file 1815
> # echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 18013
> pgsteal_anon 337
> pgsteal_file 17676
>
> After fix (swappiness=max honored, anon pages reclaimed as expected):
>
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 0
> pgsteal_anon 0
> pgsteal_file 0
> # echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
> # cat /proc/vmstat | grep pgsteal
> pgsteal_kswapd 0
> pgsteal_direct 0
> pgsteal_khugepaged 0
> pgsteal_proactive 16283
> pgsteal_anon 16283
> pgsteal_file 0
>
> Cc: stable@vger.kernel.org # 6.17+
> Fixes: b980077899ea ("mm: introduce per-node proactive reclaim interface")
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
> Reviewed-by: Barry Song <baohua@kernel.org>
> ---
> mm/vmscan.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 986dde8e7429..bd71595c8b2b 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -199,6 +199,13 @@ struct scan_control {
> */
> int vm_swappiness = 60;
>
> +static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
> +{
> + if (sc->proactive && sc->proactive_swappiness)
> + return *sc->proactive_swappiness;
> + return mem_cgroup_swappiness(memcg);
> +}
> +
> #ifdef CONFIG_MEMCG
>
> /* Returns true for reclaim through cgroup limits or cgroup interfaces. */
> @@ -239,13 +246,6 @@ static bool writeback_throttling_sane(struct scan_control *sc)
> #endif
> return false;
> }
> -
> -static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
> -{
> - if (sc->proactive && sc->proactive_swappiness)
> - return *sc->proactive_swappiness;
> - return mem_cgroup_swappiness(memcg);
> -}
> #else
> static bool cgroup_reclaim(struct scan_control *sc)
> {
> @@ -261,11 +261,6 @@ static bool writeback_throttling_sane(struct scan_control *sc)
> {
> return true;
> }
> -
> -static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
> -{
> - return READ_ONCE(vm_swappiness);
> -}
> #endif
>
> static void set_task_reclaim_state(struct task_struct *task,
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
2026-07-16 3:17 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Ridong
@ 2026-07-16 6:06 ` Tao Cui
2026-07-16 7:14 ` Barry Song
1 sibling, 0 replies; 8+ messages in thread
From: Tao Cui @ 2026-07-16 6:06 UTC (permalink / raw)
To: Ridong, Johannes Weiner, Michal Hocko, Roman Gushchin,
Shakeel Butt, Andrew Morton, Chris Li, Kairui Song
Cc: cui.tao, Muchun Song, Kemeng Shi, Nhat Pham, Baoquan He,
Barry Song, Youngjun Park, David Hildenbrand, Qi Zheng,
Lorenzo Stoakes, Axel Rasmussen, Yuanchu Xie, Wei Xu,
Davidlohr Bueso, cgroups, linux-mm, linux-kernel, Ridong Chen
Reviewed-by: Song Hu <husong@kylinos.cn>
在 2026/7/16 11:17, Ridong 写道:
> From: Ridong Chen <chenridong@xiaomi.com>
>
> The per-memcg swappiness knob is v1-only; v2 always uses global
> vm_swappiness and ignores the per-cgroup field.
>
> Both mem_cgroup_swappiness() and vm_swappiness are only used within
> mm/ (memcontrol.c, memcontrol-v1.c, vmscan.c), so move them out of the
> public include/linux/swap.h into the mm-private mm/swap.h. This keeps
> unrelated declarations out of include/linux/swap.h.
>
> Guard memcg->swappiness with CONFIG_MEMCG_V1 as well, so v2-only
> kernels drop the unused field.
>
> No functional change for v1; v2-only kernels drop the unused field.
>
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> ---
> include/linux/memcontrol.h | 4 ++--
> include/linux/swap.h | 19 -------------------
> mm/memcontrol.c | 4 ++--
> mm/swap.h | 20 ++++++++++++++++++++
> 4 files changed, 24 insertions(+), 23 deletions(-)
>
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 957260677678..e7a794dfb40e 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -239,8 +239,6 @@ struct mem_cgroup {
> */
> bool oom_group;
>
> - int swappiness;
> -
> /* memory.events and memory.events.local */
> struct cgroup_file events_file;
> struct cgroup_file events_local_file;
> @@ -318,6 +316,8 @@ struct mem_cgroup {
> /* List of events which userspace want to receive */
> struct list_head event_list;
> spinlock_t event_list_lock;
> +
> + int swappiness;
> #endif /* CONFIG_MEMCG_V1 */
>
> struct mem_cgroup_per_node *nodeinfo[];
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index 696ed01709c2..330a420fd6de 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -309,7 +309,6 @@ static inline bool lru_cache_disabled(void)
> }
>
> extern unsigned long shrink_all_memory(unsigned long nr_pages);
> -extern int vm_swappiness;
> long remove_mapping(struct address_space *mapping, struct folio *folio);
>
> #if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
> @@ -468,25 +467,7 @@ static inline int add_swap_extent(struct swap_info_struct *sis,
> }
> #endif /* CONFIG_SWAP */
> #ifdef CONFIG_MEMCG
> -static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
> -{
> - /* Cgroup2 doesn't have per-cgroup swappiness */
> - if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
> - return READ_ONCE(vm_swappiness);
> -
> - /* root ? */
> - if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg))
> - return READ_ONCE(vm_swappiness);
> -
> - return READ_ONCE(memcg->swappiness);
> -}
> -
> void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
> -#else
> -static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
> -{
> - return READ_ONCE(vm_swappiness);
> -}
> #endif
>
> #if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 22f55aeb94f3..d6ba276740ea 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -63,6 +63,7 @@
> #include <linux/sched/isolation.h>
> #include <linux/kmemleak.h>
> #include "internal.h"
> +#include "swap.h"
> #include "swap_table.h"
> #include <net/sock.h>
> #include <net/ip.h>
> @@ -4174,11 +4175,10 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
> #endif
> page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);
> if (parent) {
> - WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
> -
> page_counter_init(&memcg->memory, &parent->memory, memcg_on_dfl);
> page_counter_init(&memcg->swap, &parent->swap, false);
> #ifdef CONFIG_MEMCG_V1
> + WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
> memcg->memory.track_failcnt = !memcg_on_dfl;
> WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
> page_counter_init(&memcg->kmem, &parent->kmem, false);
> diff --git a/mm/swap.h b/mm/swap.h
> index b51ad3071a73..a0e04b97a466 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -4,6 +4,7 @@
>
> #include <linux/atomic.h> /* for atomic_long_t */
> #include <linux/mm.h> /* for PAGE_SHIFT */
> +#include <linux/memcontrol.h> /* for mem_cgroup_swappiness() */
> struct mempolicy;
> struct swap_iocb;
> struct swap_memcg_table;
> @@ -76,6 +77,25 @@ enum swap_cluster_flags {
> CLUSTER_FLAG_MAX,
> };
>
> +extern int vm_swappiness;
> +
> +static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
> +{
> +#ifdef CONFIG_MEMCG_V1
> + /* Cgroup2 doesn't have per-cgroup swappiness */
> + if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
> + return READ_ONCE(vm_swappiness);
> +
> + /* root ? */
> + if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg))
> + return READ_ONCE(vm_swappiness);
> +
> + return READ_ONCE(memcg->swappiness);
> +#else
> + return READ_ONCE(vm_swappiness);
> +#endif
> +}
> +
> #ifdef CONFIG_SWAP
> #include <linux/swapops.h> /* for swp_offset */
> #include <linux/blk_types.h> /* for bio_end_io_t */
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
2026-07-16 3:17 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Ridong
2026-07-16 6:06 ` Tao Cui
@ 2026-07-16 7:14 ` Barry Song
1 sibling, 0 replies; 8+ messages in thread
From: Barry Song @ 2026-07-16 7:14 UTC (permalink / raw)
To: Ridong
Cc: Johannes Weiner, Michal Hocko, Roman Gushchin, Shakeel Butt,
Andrew Morton, Chris Li, Kairui Song, Muchun Song, Kemeng Shi,
Nhat Pham, Baoquan He, Youngjun Park, David Hildenbrand, Qi Zheng,
Lorenzo Stoakes, Axel Rasmussen, Yuanchu Xie, Wei Xu,
Davidlohr Bueso, cgroups, linux-mm, linux-kernel, Ridong Chen
On Thu, Jul 16, 2026 at 11:18 AM Ridong <ridong.chen@linux.dev> wrote:
>
> From: Ridong Chen <chenridong@xiaomi.com>
>
> The per-memcg swappiness knob is v1-only; v2 always uses global
> vm_swappiness and ignores the per-cgroup field.
>
> Both mem_cgroup_swappiness() and vm_swappiness are only used within
> mm/ (memcontrol.c, memcontrol-v1.c, vmscan.c), so move them out of the
> public include/linux/swap.h into the mm-private mm/swap.h. This keeps
> unrelated declarations out of include/linux/swap.h.
>
> Guard memcg->swappiness with CONFIG_MEMCG_V1 as well, so v2-only
> kernels drop the unused field.
>
> No functional change for v1; v2-only kernels drop the unused field.
>
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> ---
Reviewed-by: Barry Song <baohua@kernel.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-16 7:14 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 3:17 [PATCH v2 0/2] mm: fix node reclaim swappiness handling Ridong
2026-07-16 3:17 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Ridong
2026-07-16 6:06 ` Tao Cui
2026-07-16 7:14 ` Barry Song
2026-07-16 3:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong
2026-07-16 3:25 ` Qi Zheng
2026-07-16 3:58 ` Qi Zheng
2026-07-16 6:06 ` Tao Cui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox