mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Baolin Wang <baolin.wang@linux.alibaba.com>
To: Barry Song <baohua@kernel.org>
Cc: Xiang Liu <liuxiang.277@bytedance.com>,
	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>,
	Baoquan He <baoquan.he@linux.dev>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Bo Zhang <zhangbo56@xiaomi.com>
Subject: Re: [RFC PATCH v2] mm: vmscan: avoid anon scanning for GFP_NOIO with low swapcache in MGLRU
Date: Thu, 22 Oct 2026 16:49:01 +0800	[thread overview]
Message-ID: <0cbd219d-f69d-4f72-aec5-43e1f2d978de@linux.alibaba.com> (raw)
In-Reply-To: <CAGsJ_4wV8A5snz-XE+5ht931=07SvCs_k4xvUCE1yphKyQd8tw@mail.gmail.com>



On 10/22/26 5:55 AM, Barry Song wrote:
> On Wed, Oct 21, 2026 at 3:28 PM Baolin Wang
> <baolin.wang@linux.alibaba.com> wrote:
> [...]
> 
>>>    static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
>>>    {
>>>        unsigned long total;
>>>        int swappiness = get_swappiness(lruvec, sc);
>>>        struct mem_cgroup *memcg = lruvec_memcg(lruvec);
>>>
>>> +     swappiness = get_scan_swappiness(lruvec, sc, swappiness);
>>> +
>>>        total = lruvec_evictable_size(lruvec, swappiness);
>>>
>>>        /* whether the size is big enough to be helpful */
>>> @@ -5249,9 +5265,10 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
>>>        bool need_rotate = false, should_age = false;
>>>        long nr_batch, nr_to_scan;
>>>        int swappiness = get_swappiness(lruvec, sc);
>>> +     int scan_swappiness = get_scan_swappiness(lruvec, sc, swappiness);
>>
>> IMO, 'swappiness' and 'scan_swappiness' are really confusing. Why move
>> this logic into get_swappiness()? In get_swappiness(), we already have
>> some similar logic to adjust swappiness when there is no available swap
>> space.
>>
> 
> Yes. It is very confusing. we can't do that in get_swappiness() as otherwise,
> we will get cold/hot inversion due to GFP_NOIO. for a real swappiness=0,
> we allow cold/hot inversion for anon, but for GFP_NOIO, this is not the
> case.

But can_reclaim_anon_pages() doesn't only handle the GFP_NOIO case, it 
also covers the swap space limitation scenario. The latter is what 
concerns me more.

If we're only talking about the GFP_NOIO case, I'd agree with your 
concern. However, we could introduce a helper to force anon aging and 
add comments explaining why we need this. That would look more 
maintainable than 2 confusing swappiness variables, no?

Just my 2 cents.

Something like below (untested):

diff --git a/mm/vmscan.c b/mm/vmscan.c
index daa7e37c2236..7c1d26e6b9d7 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2890,7 +2890,7 @@ static int get_swappiness(struct lruvec *lruvec, 
struct scan_control *sc)
         if (swappiness == SWAPPINESS_ANON_ONLY)
                 return swappiness;

-       if (!sc->may_swap)
+       if (!sc->may_swap || !(sc->gfp_mask & __GFP_IO))
                 return 0;

         if (!can_demote(pgdat->node_id, sc, memcg) &&
@@ -4049,7 +4049,7 @@ static inline void flush_lru_batch(struct 
list_head *head, struct list_head **ba
         *batch_end = NULL;
  }

-static bool inc_min_seq(struct lruvec *lruvec, int type, int swappiness)
+static bool inc_min_seq(struct lruvec *lruvec, int type, int 
swappiness, bool force_anon_aging)
  {
         int zone;
         int remaining = MAX_LRU_BATCH;
@@ -4063,7 +4063,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int 
type, int swappiness)
                 goto done;

         /* For anon type, skip the check if swappiness is zero (file 
only) */
-       if (!type && !swappiness)
+       if (!type && !swappiness && !force_anon_aging)
                 goto done;

         VM_WARN_ON_ONCE(get_nr_gens(lruvec, type) != MAX_NR_GENS);
@@ -4183,7 +4183,20 @@ static void try_to_inc_min_seq(struct lruvec 
*lruvec, int swappiness)
         }
  }

-static bool inc_max_seq(struct lruvec *lruvec, unsigned long seq, int 
swappiness)
+static bool is_force_anon_aging(struct scan_control *sc, struct lruvec 
*lruvec,
+               int swappiness)
+{
+       if (swappiness || (sc->gfp_mask & __GFP_IO))
+               return false;
+
+       /*
+        * Explain why we neeed to force increase anon min seq.
+        * xxxxxx
+        */
+       return swappiness != sc_swappiness(sc, lruvec_memcg(lruvec));
+}
+
+static bool inc_max_seq(struct lruvec *lruvec, unsigned long seq, int 
swappiness, bool force_anon_aging)
  {
         bool success;
         int prev, next;
@@ -4205,7 +4218,7 @@ static bool inc_max_seq(struct lruvec *lruvec, 
unsigned long seq, int swappiness
                 if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
                         continue;

-               if (inc_min_seq(lruvec, type, swappiness))
+               if (inc_min_seq(lruvec, type, swappiness, force_anon_aging))
                         continue;

                 lruvec_unlock_irq(lruvec);
@@ -4249,7 +4262,7 @@ static bool inc_max_seq(struct lruvec *lruvec, 
unsigned long seq, int swappiness
  }

  static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long seq,
-                              int swappiness, bool force_scan)
+                              int swappiness, bool force_scan, bool 
force_anon_aging)
  {
         bool success;
         struct lru_gen_mm_walk *walk;
@@ -4260,7 +4273,7 @@ static bool try_to_inc_max_seq(struct lruvec 
*lruvec, unsigned long seq,
         VM_WARN_ON_ONCE(seq > READ_ONCE(lrugen->max_seq));

         if (!mm_state)
-               return inc_max_seq(lruvec, seq, swappiness);
+               return inc_max_seq(lruvec, seq, swappiness, 
force_anon_aging);

         /* see the comment in iterate_mm_list() */
         if (seq <= READ_ONCE(mm_state->seq))
@@ -4295,7 +4308,7 @@ static bool try_to_inc_max_seq(struct lruvec 
*lruvec, unsigned long seq,
         } while (mm);
  done:
         if (success) {
-               success = inc_max_seq(lruvec, seq, swappiness);
+               success = inc_max_seq(lruvec, seq, swappiness, 
force_anon_aging);
                 WARN_ON_ONCE(!success);
         }

@@ -5262,7 +5275,9 @@ static bool try_to_shrink_lruvec(struct lruvec 
*lruvec, struct scan_control *sc)
                 }

                 if (should_run_aging(lruvec, max_seq, sc, swappiness)) {
-                       if (try_to_inc_max_seq(lruvec, max_seq, 
swappiness, false))
+                       bool force_anon_aging = is_force_anon_aging(sc, 
lruvec, swappiness);
+
+                       if (try_to_inc_max_seq(lruvec, max_seq, 
swappiness, false, force_anon_aging))
                                 need_rotate = true;
                         should_age = true;
                 }

  reply	other threads:[~2026-10-22  8:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 15:18 Xiang Liu
2026-10-21  7:28 ` Baolin Wang
2026-10-21 21:55   ` Barry Song
2026-10-22  8:49     ` Baolin Wang [this message]
2026-10-22 10:27       ` Barry Song (Xiaomi)

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=0cbd219d-f69d-4f72-aec5-43e1f2d978de@linux.alibaba.com \
    --to=baolin.wang@linux.alibaba.com \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baoquan.he@linux.dev \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=kasong@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=liuxiang.277@bytedance.com \
    --cc=ljs@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=qi.zheng@linux.dev \
    --cc=shakeel.butt@linux.dev \
    --cc=weixugc@google.com \
    --cc=yuanchu@google.com \
    --cc=zhangbo56@xiaomi.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

all inboxes | Powered by JetHome®