* Re: [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
[not found] ` <94a489d5-8b02-46e6-92d2-ccb85f556769@linux.dev>
@ 2026-07-16 11:17 ` Ridong Chen
2026-07-17 2:27 ` Qi Zheng
0 siblings, 1 reply; 6+ messages in thread
From: Ridong Chen @ 2026-07-16 11:17 UTC (permalink / raw)
To: Qi Zheng, 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/2026 4:42 PM, Qi Zheng wrote:
>
>
> On 7/16/26 4:21 PM, Ridong Chen wrote:
>>
>>
>> On 7/16/2026 11:58 AM, Qi Zheng wrote:
>>> 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.
>>
>> You're right. Currently, when can_reclaim_anon_pages() returns false,
>> the reclaim logic falls back to scanning file folios even if
>> swappiness == SWAPPINESS_ANON_ONLY is set:
>>
>> ```
>> static void get_scan_count(struct lruvec *lruvec, struct scan_control
>> *sc,
>> unsigned long *nr)
>> {
>> ....
>> /* If we have no swap space, do not bother scanning anon folios. */
>> if (!sc->may_swap || !can_reclaim_anon_pages(memcg, pgdat-
>> >node_id, sc)) {
>> scan_balance = SCAN_FILE;
>> goto out;
>> }
>>
>> ...
>> /* Proactive reclaim initiated by userspace for anonymous memory
>> only */
>> if (swappiness == SWAPPINESS_ANON_ONLY) {
>> WARN_ON_ONCE(!sc->proactive);
>> scan_balance = SCAN_ANON;
>> goto out;
>> }
>> ...
>> }
>> ```
>>
>> The !can_reclaim_anon_pages() check above takes precedence over the
>> SWAPPINESS_ANON_ONLY branch, making the latter effectively unreachable
>> when anonymous pages are deemed non-reclaimable.
>>
>> To fix this, could we move the SWAPPINESS_ANON_ONLY check up before
>> the can_reclaim_anon_pages() check?
>>
>> ```
>> static void get_scan_count(struct lruvec *lruvec, struct scan_control
>> *sc,
>> unsigned long *nr)
>> {
>> ...
>> /* Proactive reclaim initiated by userspace for anonymous memory
>> only */
>> if (swappiness == SWAPPINESS_ANON_ONLY) {
>> WARN_ON_ONCE(!sc->proactive);
>> scan_balance = SCAN_ANON;
>> goto out;
>
> For SWAPPINESS_ANON_ONLY + !can_reclaim_anon_pages, perhaps we should
> just return directly instead of goto out, since no pages can be
> reclaimed in this situation.
>
Much better.
Would you mind if I send a separate patch to fix this issue?
>
>> }
>> ....
>> /* If we have no swap space, do not bother scanning anon folios. */
>> if (!sc->may_swap || !can_reclaim_anon_pages(memcg, pgdat-
>> >node_id, sc)) {
>> scan_balance = SCAN_FILE;
>> goto out;
>> }
>>
>> ...
>> }
>> ```
>>
>
--
Best regards
Ridong
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter
2026-07-16 11:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong Chen
@ 2026-07-17 2:27 ` Qi Zheng
0 siblings, 0 replies; 6+ messages in thread
From: Qi Zheng @ 2026-07-17 2:27 UTC (permalink / raw)
To: Ridong Chen, 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 7:17 PM, Ridong Chen wrote:
>
>
> On 7/16/2026 4:42 PM, Qi Zheng wrote:
>>
>>
>> On 7/16/26 4:21 PM, Ridong Chen wrote:
>>>
>>>
>>> On 7/16/2026 11:58 AM, Qi Zheng wrote:
>>>> 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.
>>>
>>> You're right. Currently, when can_reclaim_anon_pages() returns false,
>>> the reclaim logic falls back to scanning file folios even if
>>> swappiness == SWAPPINESS_ANON_ONLY is set:
>>>
>>> ```
>>> static void get_scan_count(struct lruvec *lruvec, struct scan_control
>>> *sc,
>>> unsigned long *nr)
>>> {
>>> ....
>>> /* If we have no swap space, do not bother scanning anon folios. */
>>> if (!sc->may_swap || !can_reclaim_anon_pages(memcg, pgdat-
>>> >node_id, sc)) {
>>> scan_balance = SCAN_FILE;
>>> goto out;
>>> }
>>>
>>> ...
>>> /* Proactive reclaim initiated by userspace for anonymous memory
>>> only */
>>> if (swappiness == SWAPPINESS_ANON_ONLY) {
>>> WARN_ON_ONCE(!sc->proactive);
>>> scan_balance = SCAN_ANON;
>>> goto out;
>>> }
>>> ...
>>> }
>>> ```
>>>
>>> The !can_reclaim_anon_pages() check above takes precedence over the
>>> SWAPPINESS_ANON_ONLY branch, making the latter effectively
>>> unreachable when anonymous pages are deemed non-reclaimable.
>>>
>>> To fix this, could we move the SWAPPINESS_ANON_ONLY check up before
>>> the can_reclaim_anon_pages() check?
>>>
>>> ```
>>> static void get_scan_count(struct lruvec *lruvec, struct scan_control
>>> *sc,
>>> unsigned long *nr)
>>> {
>>> ...
>>> /* Proactive reclaim initiated by userspace for anonymous memory
>>> only */
>>> if (swappiness == SWAPPINESS_ANON_ONLY) {
>>> WARN_ON_ONCE(!sc->proactive);
>>> scan_balance = SCAN_ANON;
>>> goto out;
>>
>> For SWAPPINESS_ANON_ONLY + !can_reclaim_anon_pages, perhaps we should
>> just return directly instead of goto out, since no pages can be
>> reclaimed in this situation.
>>
>
> Much better.
> Would you mind if I send a separate patch to fix this issue?
>
Sure, thanks for your time on this, and I look forward to your fix!
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] mm: fix node reclaim swappiness handling
[not found] <20260716031729.1064007-1-ridong.chen@linux.dev>
[not found] ` <20260716031729.1064007-3-ridong.chen@linux.dev>
@ 2026-07-23 1:13 ` Ridong Chen
2026-07-23 1:54 ` Andrew Morton
[not found] ` <20260716031729.1064007-2-ridong.chen@linux.dev>
2 siblings, 1 reply; 6+ messages in thread
From: Ridong Chen @ 2026-07-23 1:13 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
On 7/16/2026 11:17 AM, Ridong wrote:
> 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(-)
>
Hello all,
Can this series be applied?
Just a reminder in case this gets buried.
--
Best regards
Ridong
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] mm: fix node reclaim swappiness handling
2026-07-23 1:13 ` [PATCH v2 0/2] mm: fix node reclaim swappiness handling Ridong Chen
@ 2026-07-23 1:54 ` Andrew Morton
0 siblings, 0 replies; 6+ messages in thread
From: Andrew Morton @ 2026-07-23 1:54 UTC (permalink / raw)
To: Ridong Chen
Cc: Johannes Weiner, Michal Hocko, Roman Gushchin, Shakeel Butt,
Chris Li, Kairui Song, 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
On Thu, 23 Jul 2026 09:13:27 +0800 Ridong Chen <ridong.chen@linux.dev> wrote:
> > 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(-)
> >
>
> Hello all,
>
> Can this series be applied?
>
> Just a reminder in case this gets buried.
Got it, and thanks for the poke.
It seems that kvack.org sent me two of the emails from this 13 email
thread. This is becoming a problem.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
[not found] ` <20260716031729.1064007-2-ridong.chen@linux.dev>
@ 2026-07-23 1:59 ` Johannes Weiner
2026-07-23 2:14 ` Ridong Chen
0 siblings, 1 reply; 6+ messages in thread
From: Johannes Weiner @ 2026-07-23 1:59 UTC (permalink / raw)
To: Ridong
Cc: Michal Hocko, Roman Gushchin, Shakeel Butt, Andrew Morton,
Chris Li, Kairui Song, 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
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
One small suggestion:
On Thu, Jul 16, 2026 at 11:17:28AM +0800, Ridong wrote:
> @@ -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
How about:
#ifdef CONFIG_MEMCG_V1
if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
!mem_cgroup_disabled() && !mem_cgroup_is_root(memcg))
return memcg->swappiness;
#endif
return READ_ONCE(vm_swappiness);
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h
2026-07-23 1:59 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Johannes Weiner
@ 2026-07-23 2:14 ` Ridong Chen
0 siblings, 0 replies; 6+ messages in thread
From: Ridong Chen @ 2026-07-23 2:14 UTC (permalink / raw)
To: Johannes Weiner, Andrew Morton
Cc: Michal Hocko, Roman Gushchin, Shakeel Butt, Andrew Morton,
Chris Li, Kairui Song, 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
On 7/23/2026 9:59 AM, Johannes Weiner wrote:
> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
>
> One small suggestion:
>
> On Thu, Jul 16, 2026 at 11:17:28AM +0800, Ridong wrote:
>> @@ -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
>
> How about:
>
> #ifdef CONFIG_MEMCG_V1
> if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
> !mem_cgroup_disabled() && !mem_cgroup_is_root(memcg))
> return memcg->swappiness;
> #endif
> return READ_ONCE(vm_swappiness);
This is simpler.
Hi, Andrew, I notice you just applied this series to mm-new branch. Would you
mind I update it?
--
Best regards
Ridong
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-23 2:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260716031729.1064007-1-ridong.chen@linux.dev>
[not found] ` <20260716031729.1064007-3-ridong.chen@linux.dev>
[not found] ` <7ddf3eee-5fe2-45f7-8614-c8936a039e04@linux.dev>
[not found] ` <a5eb5433-cf6c-40ee-b14e-128a8bcc85bf@linux.dev>
[not found] ` <94a489d5-8b02-46e6-92d2-ccb85f556769@linux.dev>
2026-07-16 11:17 ` [PATCH v2 2/2] mm: vmscan: fix node reclaim ignoring swappiness parameter Ridong Chen
2026-07-17 2:27 ` Qi Zheng
2026-07-23 1:13 ` [PATCH v2 0/2] mm: fix node reclaim swappiness handling Ridong Chen
2026-07-23 1:54 ` Andrew Morton
[not found] ` <20260716031729.1064007-2-ridong.chen@linux.dev>
2026-07-23 1:59 ` [PATCH v2 1/2] memcg: move mem_cgroup_swappiness and vm_swappiness to mm/swap.h Johannes Weiner
2026-07-23 2:14 ` Ridong Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox