[PATCH 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter

From: Ridong Chen

Date: Sat Jul 11 2026 - 05:13:09 EST


From: Ridong Chen <chenridong@xxxxxxxxxx>

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

Fixes: 68cd9050d871 ("mm: add swappiness= arg to memory.reclaim")
Signed-off-by: Ridong Chen <chenridong@xxxxxxxxxx>
---
mm/vmscan.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 35c3bb15ae96..5271bd023c1d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -198,6 +198,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,12 +246,6 @@ static bool writeback_throttling_sane(struct scan_control *sc)
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,10 +262,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.43.0