All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
To: devnull+kasong.tencent.com@kernel.org
Cc: akpm@linux-foundation.org, axelrasmussen@google.com,
	baohua@kernel.org, baolin.wang@linux.alibaba.com,
	baoquan.he@linux.dev, cgroups@vger.kernel.org,
	chenridong@xiaomi.com, chrisl@kernel.org, damon@lists.linux.dev,
	david@kernel.org, dev.jain@arm.com, ehab.ababneh@intel.com,
	gourry@gourry.net, hannes@cmpxchg.org, hughd@google.com,
	kasong@tencent.com, kunwu.chan@gmail.com, lance.yang@linux.dev,
	liam@infradead.org, lianux.mm@gmail.com,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	liuxiang.277@bytedance.com, ljs@kernel.org, mhocko@kernel.org,
	muchun.song@linux.dev, nico.pache@linux.dev, nphamcs@gmail.com,
	qi.zheng@linux.dev, rientjes@google.com,
	roman.gushchin@linux.dev, ryan.roberts@arm.com, ryncsn@gmail.com,
	shakeel.butt@linux.dev, shikemeng@huaweicloud.com, sj@kernel.org,
	surenb@google.com, tz2294@columbia.edu, usama.arif@linux.dev,
	vbabka@kernel.org, vernon2gm@gmail.com, wangzicheng@honor.com,
	weixugc@google.com, willy@infradead.org,
	ying.huang@linux.alibaba.com, youngjun.park@lge.com,
	yuanchu@google.com, yuzhao@google.com,
	zhaozhengzhuo@uniontech.com, ziy@nvidia.com,
	stable@vger.kernel.org
Subject: Re: [PATCH v4 00/17] mm/mglru: frequency guided promotion (MGLRU-FG) and flag cleanup
Date: Fri, 16 Oct 2026 16:42:56 +0800	[thread overview]
Message-ID: <20261016084256.12955-1-baohua@kernel.org> (raw)
In-Reply-To: <20261016-mglru-fg-v4-0-2106750c0bfa@tencent.com>

On Fri, Oct 16, 2026 at 2:15 AM Kairui Song via B4 Relay <devnull+kasong.tencent.com@kernel.org> wrote:
[...]
>
> LevelDB Scan/Get
> ================
> I also retested the LevelDB benchmark from the cache_ext paper [5].
> Interestingly, mainline MGLRU already beats CLRU on this one after a
> recent change in lru_gen_folio_seq that bumps new folios with refs == 1
> to the second-oldest generation as discussed. That change accidentally
> gave random reads a higher hotness level while making sequential reads
> much colder as described before [14]. However it's unreliable and
> incorrect because it depends on LRU drain timing, and hurts some workloads
> as reported, or where the sequential part is actually hotter (any workload
> involving hotter large file and many small cold files will be affected)
> which is reproduced below.
>
> This series improves it while covering ordinary workloads too and should
> fix regressions:
>
> LevelDB Scan / Get, Throughput Total:
> CLRU:         4708.3 ops/s
> MGLRU:        5026.9 ops/s (faster than CLRU, but hurts other workloads)
> MGLRU After:  5179.2 ops/s (even better in all cases, and no regression)
>
> The hot-sequential and cold-random workload can be easily reproduced with
> SQLite and grep. SQLite continuously scans and looks up a small hot
> portion of a DB file, while grep iterates over a set of small files much
> larger than RAM [6]:
>
>          SQLite scan & lookup time:       Grep iterate time:
> CLRU:                       14.51ms               13281.37ms
> MGLRU mainline:            567.05ms               13694.47ms
> MGLRU After this series:    10.58ms               12930.43ms
>

Thanks, Kairui. I'll do a thorough review of the whole patchset over
the next two weeks.

BTW, do you think we need a quick fix patch like the one below
for the above problem before this patchset, so that it can be
backported to stable? I assume your patchset is too large to
backport?

From f9683205d2ab6e3b185022d7d5af3496dfe5f35f Mon Sep 17 00:00:00 2001
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
Date: Fri, 16 Oct 2026 11:48:06 +0800
Subject: [PATCH] mm/mglru: fix using folio_mark_accessed to replace
 folio_set_active

Commit 6cbdd9726fb5 ("mm/mglru: use folio_mark_accessed to
replace folio_set_active") tried to avoid over-protecting
fault-around read-ahead file folios by placing them in the
second-oldest generation instead of the youngest generations.

However, it abuses `PG_referenced` on read-ahead file folios
for this purpose, potentially coupling their handling with
normal syscall-based file accesses that also use
`PG_referenced`.

This could regress some workloads, as reported by Kairui Song[1]
and Ehab Ababneh[2]. Many thanks to both for reporting these
issues!

The long-term fix is Kairui's MGLRU-FG, but in the meantime,
we also need a quick fix that can be backported to stable.

This patch reverts all of the original commit's behavior that
abuses `PG_referenced`, while preserving the semantics of
avoiding over-protection of fault-around read-ahead file
folios by adjusting only `lru_gen_folio_seq()`.
Specifically, fault-around read-ahead file folios with
`PG_active` set but `PG_workingset` clear are placed in the
second-oldest generation.
Activated file folios and refaulted workingset file folios
are still placed in the youngest generations.

Build kernel cases in a memcg shows it not only perserve
the benefit of original patch, but also even improve
performance further.

w/o fix:

real    1m49.094s
user    25m31.484s
sys     3m40.959s
pswpin: 662112
pswpout: 2504415
pgpgin: 4424336
pgpgout: 10355273
refault_file: 359626
refault_anon: 670724

w/ fix:

real	1m48.913s
user	25m31.639s
sys	3m30.875s
pswpin: 689815
pswpout: 2689894
pgpgin: 4422659
pgpgout: 11043464
refault_file: 326566
refault_anon: 697138

Revert original patch:

real	1m50.044s
user	25m37.137s
sys	4m4.493s
pswpin: 1349087
pswpout: 4317933
pgpgin: 7083597
pgpgout: 17602735
refault_file: 337676
refault_anon: 1368542

[1] https://lore.kernel.org/linux-mm/20261003-mglru-fg-v3-0-cbd4546a5bd9@tencent.com/
[2] https://lore.kernel.org/linux-mm/20260901180704.168106-1-ehab.ababneh@intel.com/
Fixes: 6cbdd9726fb5 ("mm/mglru: use folio_mark_accessed to replace folio_set_active")
Cc: <stable@vger.kernel.org>
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
---
 include/linux/mm_inline.h |  8 +++++---
 mm/folio.c                | 16 +++-------------
 mm/vmscan.c               |  9 ++-------
 mm/workingset.c           | 10 ++++------
 4 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index ab69b9930893..7aaff4e06e80 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -311,7 +311,8 @@ static inline unsigned long lru_gen_folio_seq(const struct lruvec *lruvec,
 	 * | Accessed through page tables and  | Accessed through file descriptors |
 	 * | promoted by folio_update_gen()    | and protected by folio_inc_gen()  |
 	 * +-----------------------------------+-----------------------------------+
-	 * | PG_active (set while isolated)    |                                   |
+	 * | PG_active (set while isolated)    | PG_active (files|                 |
+	 * |                                   | fault-readahead)|                 |
 	 * +-----------------+-----------------+-----------------+-----------------+
 	 * |  PG_workingset  |  PG_referenced  |  PG_workingset  |  LRU_REFS_FLAGS |
 	 * +-----------------------------------+-----------------------------------+
@@ -319,7 +320,8 @@ static inline unsigned long lru_gen_folio_seq(const struct lruvec *lruvec,
 	 * |<---------------------------- MAX_NR_GENS ---------------------------->|
 	 */
 	if (folio_test_active(folio))
-		gen = MIN_NR_GENS - folio_test_workingset(folio);
+		gen = MIN_NR_GENS - folio_test_workingset(folio) +
+		      (type ? !folio_test_workingset(folio) : 0);
 	else if (reclaiming)
 		gen = MAX_NR_GENS;
 	else if ((!folio_is_file_lru(folio) && !folio_test_swapcache(folio)) ||
@@ -327,7 +329,7 @@ static inline unsigned long lru_gen_folio_seq(const struct lruvec *lruvec,
 		  (folio_test_dirty(folio) || folio_test_writeback(folio))))
 		gen = MIN_NR_GENS;
 	else
-		gen = MAX_NR_GENS - (folio_test_workingset(folio) || folio_test_referenced(folio));
+		gen = MAX_NR_GENS - folio_test_workingset(folio);

 	return max(READ_ONCE(lrugen->max_seq) - gen + 1, READ_ONCE(lrugen->min_seq[type]));
 }
diff --git a/mm/folio.c b/mm/folio.c
index 35e242b48870..2af724cecb31 100644
--- a/mm/folio.c
+++ b/mm/folio.c
@@ -474,20 +474,10 @@ void folio_add_lru(struct folio *folio)
 			folio_test_unevictable(folio), folio);
 	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);

-	/*
-	 * For refaulted workingset folios, set PG_active so they
-	 * can be added to active generations.
-	 * For prefaulted file folios, folio_mark_accessed() sets
-	 * PG_referenced so lru_gen_folio_seq() places them into
-	 * the second oldest generation.
-	 */
+	/* see the comment in lru_gen_folio_seq() */
 	if (lru_gen_enabled() && !folio_test_unevictable(folio) &&
-	    lru_gen_in_fault() && !(current->flags & PF_MEMALLOC)) {
-		if (folio_test_workingset(folio))
-			folio_set_active(folio);
-		else if (!folio_test_referenced(folio))
-			folio_mark_accessed(folio);
-	}
+	    lru_gen_in_fault() && !(current->flags & PF_MEMALLOC))
+		folio_set_active(folio);

 	folio_batch_add_and_move(folio, lru_add);
 }
diff --git a/mm/vmscan.c b/mm/vmscan.c
index daa7e37c2236..e82ba737c028 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -952,13 +952,8 @@ static bool lru_gen_set_refs(struct folio *folio, const vma_flags_t *vma_flags)
 		return false;
 	}

-	/* Promote on second access */
-	if (folio_lru_refs(folio) > 1) {
-		folio_set_workingset(folio);
-		folio_set_lru_refs(folio, 0);
-	} else {
-		folio_mark_accessed(folio);
-	}
+	folio_set_workingset(folio);
+	folio_set_lru_refs(folio, 0);
 	return true;
 }
 #else
diff --git a/mm/workingset.c b/mm/workingset.c
index 1504f91cdca5..10d4ce202cca 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -319,13 +319,11 @@ static void lru_gen_refault(struct folio *folio, void *shadow)

 	atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]);

+	/* see folio_add_lru() where folio_set_active() will be called */
+	if (lru_gen_in_fault())
+		mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta);
+
 	if (workingset) {
-		/*
-		 * see folio_add_lru(), where folio_set_active() is
-		 * called for workingset folios
-		 */
-		if (lru_gen_in_fault())
-			mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta);
 		folio_set_workingset(folio);
 		mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta);
 	} else
--
2.34.1


      parent reply	other threads:[~2026-10-16  8:43 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 18:15 [PATCH v4 00/17] mm/mglru: frequency guided promotion (MGLRU-FG) and flag cleanup Kairui Song via B4 Relay
2026-10-15 18:15 ` Kairui Song
2026-10-15 18:15 ` [PATCH v4 01/17] mm/memcontrol: allow update of LRU statistic without holding LRU lock Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:32   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 02/17] mm/mglru: make generation page counters atomic Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:37   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 03/17] mm/memcg: add folio-based lruvec live helper Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:31   ` sashiko-bot
2026-10-15 19:11   ` Harry Yoo
2026-10-16  6:15     ` Kairui Song
2026-10-16  7:39   ` Muchun Song
2026-10-16  7:54     ` Kairui Song
2026-10-16  9:09       ` Muchun Song
2026-10-15 18:15 ` [PATCH v4 04/17] mm/mglru: frequency guided workingset promotion (MGLRU-FG) Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:41   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 05/17] mm/mglru: make folio lru referenced times count a generic API Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:30   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 06/17] mm/mglru: move add/del LRU size accounting out of lru_gen_update_size() Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:28   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 07/17] mm/mglru, gup: mark folios referenced via a fast helper Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:27   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 08/17] mm/mglru, smaps: convert to LRU refs based operations for MGLRU Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:29   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 09/17] mm/damon: " Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:27   ` sashiko-bot
2026-10-15 18:15 ` [PATCH v4 10/17] mm/khugepaged: " Kairui Song via B4 Relay
2026-10-15 18:15   ` Kairui Song
2026-10-15 18:29   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 11/17] mm/madvise: adapt for " Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:25   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 12/17] mm/huge_memory: mark folio as accessed more accurately on split Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:36   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 13/17] mm/mglru: folio LRU refs based active/inactive number accounting Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:34   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 14/17] mm/mglru: reparent folios from all generations Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:27   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 15/17] mm/mglru: make folio_inc_lru_refs lruvec lockless Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:29   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 16/17] mm/mglru: make folio_test_workingset() work based on folio LRU refs Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:35   ` sashiko-bot
2026-10-15 18:16 ` [PATCH v4 17/17] Documentation/mm: multi-gen LRU: update for frequency guided promotion Kairui Song via B4 Relay
2026-10-15 18:16   ` Kairui Song
2026-10-15 18:27   ` sashiko-bot
2026-10-16  8:42 ` Barry Song (Xiaomi) [this message]

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=20261016084256.12955-1-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=cgroups@vger.kernel.org \
    --cc=chenridong@xiaomi.com \
    --cc=chrisl@kernel.org \
    --cc=damon@lists.linux.dev \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=devnull+kasong.tencent.com@kernel.org \
    --cc=ehab.ababneh@intel.com \
    --cc=gourry@gourry.net \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=kasong@tencent.com \
    --cc=kunwu.chan@gmail.com \
    --cc=lance.yang@linux.dev \
    --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=ljs@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=muchun.song@linux.dev \
    --cc=nico.pache@linux.dev \
    --cc=nphamcs@gmail.com \
    --cc=qi.zheng@linux.dev \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=ryan.roberts@arm.com \
    --cc=ryncsn@gmail.com \
    --cc=shakeel.butt@linux.dev \
    --cc=shikemeng@huaweicloud.com \
    --cc=sj@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=surenb@google.com \
    --cc=tz2294@columbia.edu \
    --cc=usama.arif@linux.dev \
    --cc=vbabka@kernel.org \
    --cc=vernon2gm@gmail.com \
    --cc=wangzicheng@honor.com \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --cc=ying.huang@linux.alibaba.com \
    --cc=youngjun.park@lge.com \
    --cc=yuanchu@google.com \
    --cc=yuzhao@google.com \
    --cc=zhaozhengzhuo@uniontech.com \
    --cc=ziy@nvidia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.