From: "Barry Song (Xiaomi)" <baohua@kernel.org>
To: akpm@linux-foundation.org, linux-mm@kvack.org
Cc: axelrasmussen@google.com, baolin.wang@linux.alibaba.com,
baoquan.he@linux.dev, hannes@cmpxchg.org, hui.zhu@linux.dev,
kasong@tencent.com, kunwu.chan@gmail.com, liam@infradead.org,
lianux.mm@gmail.com, linux-kernel@vger.kernel.org,
liuxiang.277@bytedance.com, lyugaofei@xiaomi.com,
mhocko@kernel.org, mhocko@suse.com, qi.zheng@linux.dev,
ridong.chen@linux.dev, rppt@kernel.org, ryncsn@gmail.com,
shakeel.butt@linux.dev, surenb@google.com, wangzicheng@honor.com,
weixugc@google.com, yuanchu@google.com, zhangbo56@xiaomi.com,
zhuhui@kylinos.cn, sidchintamaneni@gmail.com,
Barry Song <baohua@kernel.org>
Subject: [PATCH v9 10/16] mm/mglru: Run aging when pages are rare outside the youngest gen
Date: Sun, 15 Nov 2026 04:07:57 +0800 [thread overview]
Message-ID: <20261114200803.23129-11-baohua@kernel.org> (raw)
In-Reply-To: <20261114200803.23129-1-baohua@kernel.org>
From: Gaofei Lyu <lyugaofei@xiaomi.com>
Run aging when the total number of pages outside the youngest
generation across both types falls below 1/MAX_NR_GENS of the number
of pages in the youngest generation. For extreme swappiness values
such as 1 and 200, also consider the balance of the corresponding
type.
This improves reclaim efficiency, especially at extreme swappiness
values, while reducing system time.
To avoid the overhead of aging, we only allow imbalance-based aging
when the reclaim priority is low enough that we might reclaim the
youngest generation.
Signed-off-by: Gaofei Lyu <lyugaofei@xiaomi.com>
Co-developed-by: Barry Song (Xiaomi) <baohua@kernel.org>
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
---
mm/vmscan.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0fef966b0a14..1450542d709c 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2743,6 +2743,8 @@ static bool should_clear_pmd_young(void)
#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS)
#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS)
+#define AGING_PRIORITY (DEF_PRIORITY / 2)
+
static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
{
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
@@ -4780,7 +4782,7 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
*/
if (sc->priority == DEF_PRIORITY)
seq = lrugen->max_seq - MIN_NR_GENS;
- else if (sc->priority > DEF_PRIORITY / 2)
+ else if (sc->priority > AGING_PRIORITY)
seq = lrugen->max_seq - 1;
else
seq = lrugen->max_seq;
@@ -5073,6 +5075,40 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
return scanned;
}
+static bool lru_gen_imbalanced(struct lruvec *lruvec, struct scan_control *sc,
+ int swappiness)
+{
+ unsigned long youngest[ANON_AND_FILE] = {0}, old[ANON_AND_FILE] = {0};
+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
+ DEFINE_MAX_SEQ(lruvec);
+ DEFINE_MIN_SEQ(lruvec);
+ int type;
+
+ if (sc->priority > AGING_PRIORITY)
+ return false;
+
+ /*
+ * Round up or down corner swappiness, to balance the heavy biased
+ * type better
+ */
+ if (swappiness == MIN_SWAPPINESS + 1)
+ swappiness = MIN_SWAPPINESS;
+ else if (swappiness == MAX_SWAPPINESS)
+ swappiness = MAX_SWAPPINESS + 1;
+
+ for_each_evictable_type(type, swappiness) {
+ unsigned long seq;
+
+ youngest[type] = lruvec_gen_size(lrugen, type, max_seq);
+ for (seq = min_seq[type]; seq < max_seq; seq++)
+ old[type] += lruvec_gen_size(lrugen, type, seq);
+ }
+
+ /* the vast majority of pages sit in the youngest gen */
+ return youngest[LRU_GEN_ANON] + youngest[LRU_GEN_FILE] >
+ (old[LRU_GEN_ANON] + old[LRU_GEN_FILE]) * MAX_NR_GENS;
+}
+
static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
struct scan_control *sc, int swappiness)
{
@@ -5087,7 +5123,11 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
return false;
/* better to run aging even though eviction is still possible */
- return evictable_min_seq(min_seq, swappiness) + MIN_NR_GENS == max_seq;
+ if (evictable_min_seq(min_seq, swappiness) + MIN_NR_GENS == max_seq)
+ return true;
+
+ /* run aging when folios outside the youngest gen are rare */
+ return lru_gen_imbalanced(lruvec, sc, swappiness);
}
static void lru_gen_prepare_scan(struct lruvec *lruvec, struct scan_control *sc,
--
2.39.3 (Apple Git-146)
next prev parent reply other threads:[~2026-11-14 20:09 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 20:07 [PATCH v9 00/16] mm: mglru: fix swappiness behavior Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 01/16] mm/mglru: report evictable sizes per type Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 02/16] mm/mglru: extract lruvec_populated_min_seq() helper Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 03/16] mm/mglru: reclaim from the oldest populated gen Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 04/16] mm/mglru: lift the forced protection of reclaimer Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 05/16] mm/mglru: skip zones above reclaim_idx instead of rotating them Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 06/16] mm/mglru: return for unavailable anon reclaim earlier Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 07/16] mm/mglru: balance anon and file scan budget by refault rate Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 08/16] mm/mglru: lift youngest gen protection for higher priority Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 09/16] mm/mglru: Avoid placing rejected folios below populated gen Barry Song (Xiaomi)
2026-11-14 20:07 ` Barry Song (Xiaomi) [this message]
2026-11-14 20:07 ` [PATCH v9 11/16] mm/mglru: Run aging when one type is drained Barry Song (Xiaomi)
2026-11-14 20:07 ` [PATCH v9 12/16] mm/mglru: Restrict eviction accounting to eligible zones Barry Song (Xiaomi)
2026-11-14 20:08 ` [PATCH v9 13/16] mm/mglru: Reduce LRU lock contention by shrinking folio batches in inc_min_seq Barry Song (Xiaomi)
2026-11-14 20:08 ` [PATCH v9 14/16] mm/mglru: Avoid prolonged anon reclaim with swappiness=200 Barry Song (Xiaomi)
2026-11-14 20:08 ` [PATCH v9 15/16] mm/mglru: Make swappiness=1 file reclaim more aggressive Barry Song (Xiaomi)
2026-11-14 20:08 ` [PATCH v9 16/16] mm/mglru: Avoid scan anon while swapcache is low for GFP_NOIO allocation 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=20261114200803.23129-11-baohua@kernel.org \
--to=baohua@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=hannes@cmpxchg.org \
--cc=hui.zhu@linux.dev \
--cc=kasong@tencent.com \
--cc=kunwu.chan@gmail.com \
--cc=liam@infradead.org \
--cc=lianux.mm@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=liuxiang.277@bytedance.com \
--cc=lyugaofei@xiaomi.com \
--cc=mhocko@kernel.org \
--cc=mhocko@suse.com \
--cc=qi.zheng@linux.dev \
--cc=ridong.chen@linux.dev \
--cc=rppt@kernel.org \
--cc=ryncsn@gmail.com \
--cc=shakeel.butt@linux.dev \
--cc=sidchintamaneni@gmail.com \
--cc=surenb@google.com \
--cc=wangzicheng@honor.com \
--cc=weixugc@google.com \
--cc=yuanchu@google.com \
--cc=zhangbo56@xiaomi.com \
--cc=zhuhui@kylinos.cn \
/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