Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Ridong Chen <ridong.chen@linux.dev>
To: Barry Song <baohua@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Johannes Weiner <hannes@cmpxchg.org>,
	David Hildenbrand <david@kernel.org>,
	Michal Hocko <mhocko@kernel.org>, Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Lorenzo Stoakes <ljs@kernel.org>,
	Kairui Song <kasong@tencent.com>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	Zhongkun He <hezhongkun.hzk@bytedance.com>,
	Muchun Song <muchun.song@linux.dev>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Roman Gushchin <roman.gushchin@linux.dev>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Ridong Chen <chenridong@xiaomi.com>
Subject: Re: [PATCH v3 4/4] mm/mglru: fix anon-only reclaim evicting file pages when swappiness=max
Date: Fri, 24 Jul 2026 10:20:40 +0800	[thread overview]
Message-ID: <5b26565b-300a-498e-afb3-e5ee1d7fe84b@linux.dev> (raw)
In-Reply-To: <CAGsJ_4wtcP87bTPmm+aQ3pxn4eLW7KqU-0DJhBF639Muc2xzjg@mail.gmail.com>



On 7/23/2026 4:57 PM, Barry Song wrote:
> On Thu, Jul 23, 2026 at 12:58 PM Ridong <ridong.chen@linux.dev> wrote:
>>
>> From: Ridong Chen <chenridong@xiaomi.com>
>>
>> The previous patch fixed this issue for the traditional LRU. The same
>> problem exists in MGLRU [1]: when swappiness=max (SWAPPINESS_ANON_ONLY)
>> is set, reclaim is expected to evict anonymous pages exclusively, but
>> file pages can still be reclaimed when anonymous pages cannot be
>> reclaimed (e.g. no swap and no demotion target).
>>
>> With SWAPPINESS_ANON_ONLY, get_type_to_scan() always returns
>> LRU_GEN_ANON and for_each_evictable_type() only iterates the anon type.
>> But if get_nr_to_scan() does not bail out, evict_folios() still runs and
>> isolate_folios() falls back to scanning file pages in the !scanned case:
>>
>>    shrink_one
>>      try_to_shrink_lruvec
>>        get_swappiness   // returns SWAPPINESS_ANON_ONLY for swappiness=max
>>        get_nr_to_scan
>>        evict_folios
>>          isolate_folios // falls back to file type when !scanned
>>
> 
> I am not convinced this is correct. Although we do have `type = !type`,
> when `swappiness == 201`, `for_each_evictable_type()` stops iterating
> after trying a single type, so there is no opportunity to fall back.
> 
> #define for_each_evictable_type(type, swappiness)                       \
>          for ((type) = min_type(swappiness); (type) <=
> max_type(swappiness); (type)++)
> 

You're right. In my initial version, the intention was to bail out early and 
avoid unnecessary work.

I recall that during your review of Kairui's series, you sent a patch that used 
a fallback mechanism with type = !type. I was thinking that this could become an 
issue if we call isolate_folios() when swappiness is set to max.

> So I'm really curious what's happening here.
> 
> static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
>                            struct scan_control *sc, int swappiness,
>                            struct list_head *list, int *isolated,
>                            int *isolate_type, int *isolate_scanned)
> {
>          int i;
>          int total_scanned = 0;
>          int type = get_type_to_scan(lruvec, swappiness);
> 
>          for_each_evictable_type(i, swappiness) {
>                  int scanned;
>                  int tier = get_tier_idx(lruvec, type);
> 
>                  scanned = scan_folios(nr_to_scan, lruvec, sc,
>                                        type, tier, list, isolated);
> 
>                  ...
>                  if (!scanned)
>                          type = !type;
>          }
> 
>          return total_scanned;
> }
> 
> since both min and max types are anon:
> #define min_type(swappiness) (!(swappiness))
> #define max_type(swappiness) ((swappiness) < SWAPPINESS_ANON_ONLY)
> 
> I guess the real problem only occurs when `may_swap` is false?
I added some trace logs to verify this behavior. If we don't make 
get_nr_to_scan() return 0 when swappiness=max, it won't fall back to scanning 
file pages, but it will still perform useless scanning that yields no reclaim.

Log:
   # echo "64M swappiness=max" > memory.reclaim
   [   78.914972] vmscan: in isolate_folios swappness 201
   [   78.916841] vmscan: call scan_folios type 0
   [   78.918311] vmscan: fall back 1  <-  can't call scan_folios, loop ends.
   [   78.919479] vmscan: out isolate_folios total_scanned 0
   [...]

   # cat memory.stat | grep proactive
   pgdemote_proactive 0
   pgsteal_proactive 0
   pgscan_proactive 1808

I will update the commit message to clarify that get_nr_to_scan() returns 0 to 
avoid this useless work.

-- 
Best regards
Ridong



  reply	other threads:[~2026-07-24  2:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23  4:57 [PATCH v3 0/4] mm/vmscan: fix swappiness=max and clean up per-node proactive reclaim Ridong
2026-07-23  4:57 ` [PATCH v3 1/4] mm/vmscan: fix anon-only reclaim evicting file pages when swappiness=max Ridong
2026-07-23  4:57 ` [PATCH v3 2/4] mm: vmscan: propagate real error code from per-node proactive reclaim Ridong
2026-07-23  4:57 ` [PATCH v3 3/4] mm: vmscan: drop unused gfp_mask parameter from __node_reclaim() Ridong
2026-07-23  4:57 ` [PATCH v3 4/4] mm/mglru: fix anon-only reclaim evicting file pages when swappiness=max Ridong
2026-07-23  8:57   ` Barry Song
2026-07-24  2:20     ` Ridong Chen [this message]
2026-07-24  0:18 ` [PATCH v3 0/4] mm/vmscan: fix swappiness=max and clean up per-node proactive reclaim Andrew Morton
2026-07-24  2:27   ` Ridong Chen
2026-07-24  2:43   ` Ridong Chen

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=5b26565b-300a-498e-afb3-e5ee1d7fe84b@linux.dev \
    --to=ridong.chen@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=chenridong@xiaomi.com \
    --cc=dave@stgolabs.net \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=hezhongkun.hzk@bytedance.com \
    --cc=kasong@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=muchun.song@linux.dev \
    --cc=qi.zheng@linux.dev \
    --cc=roman.gushchin@linux.dev \
    --cc=shakeel.butt@linux.dev \
    --cc=weixugc@google.com \
    --cc=yuanchu@google.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