From: "Barry Song (Xiaomi)" <baohua@kernel.org>
To: akpm@linux-foundation.org, linux-mm@kvack.org
Cc: axelrasmussen@google.com, chenridong@xiaomi.com,
david@kernel.org, hannes@cmpxchg.org, kasong@tencent.com,
lianux.mm@gmail.com, linux-kernel@vger.kernel.org,
ljs@kernel.org, lyugaofei@xiaomi.com, mhocko@kernel.org,
qi.zheng@linux.dev, shakeel.butt@linux.dev,
stevensd@chromium.org, wangzicheng@honor.com, weixugc@google.com,
yuanchu@google.com, zhangbo56@xiaomi.com,
baolin.wang@linux.alibaba.com, baoquan.he@linux.dev,
"Barry Song (Xiaomi)" <baohua@kernel.org>
Subject: [RFC PATCH v4 05/16] mm/mglru: batch update lrugen->nr_pages in inc_min_seq()
Date: Wed, 12 Aug 2026 20:16:47 +0800 [thread overview]
Message-ID: <20260812121658.69965-6-baohua@kernel.org> (raw)
In-Reply-To: <20260812121658.69965-1-baohua@kernel.org>
Currently, folio_inc_gen() updates lrugen->nr_pages for every folio
as it advances generations. Instead, accumulate the size changes
and update lrugen->nr_pages in a batch after scanning the entire
oldest generation, or when the scan stops because remaining reaches
zero.
Since we only move folios from the oldest generation to the second
oldest generation, the active/inactive state cannot change. We can
therefore skip __lru_update_size().
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
---
mm/vmscan.c | 46 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2fd1e06eb192..c6e3b92c8cae 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3295,20 +3295,21 @@ static int folio_update_gen(struct folio *folio, int gen, const vma_flags_t *vma
}
/* protect pages accessed multiple times through file descriptors */
-static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio)
+static int __folio_inc_gen(struct folio *folio, int old_gen, bool *increased)
{
- int type = folio_is_file_lru(folio);
- struct lru_gen_folio *lrugen = &lruvec->lrugen;
- int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
unsigned long new_flags, old_flags = READ_ONCE(folio->flags.f);
+ int new_gen;
VM_WARN_ON_ONCE_FOLIO(!(old_flags & LRU_GEN_MASK), folio);
do {
new_gen = ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
/* folio_update_gen() has promoted this page? */
- if (new_gen >= 0 && new_gen != old_gen)
+ if (new_gen >= 0 && new_gen != old_gen) {
+ if (increased)
+ *increased = false;
return new_gen;
+ }
new_gen = (old_gen + 1) % MAX_NR_GENS;
@@ -3316,8 +3317,21 @@ static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio)
new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
} while (!try_cmpxchg(&folio->flags.f, &old_flags, new_flags));
- lru_gen_update_size(lruvec, folio, old_gen, new_gen);
+ if (increased)
+ *increased = true;
+ return new_gen;
+}
+static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio)
+{
+ int type = folio_is_file_lru(folio);
+ struct lru_gen_folio *lrugen = &lruvec->lrugen;
+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
+ bool gen_increased;
+
+ new_gen = __folio_inc_gen(folio, old_gen, &gen_increased);
+ if (gen_increased)
+ lru_gen_update_size(lruvec, folio, old_gen, new_gen);
return new_gen;
}
@@ -3903,6 +3917,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, int swappiness)
struct lru_gen_folio *lrugen = &lruvec->lrugen;
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
+ int target_gen = (old_gen + 1) % MAX_NR_GENS;
/* For file type, skip the check if swappiness is anon only */
if (type && (swappiness == SWAPPINESS_ANON_ONLY))
@@ -3915,32 +3930,41 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, int swappiness)
/* prevent cold/hot inversion if the type is evictable */
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
struct list_head *head = &lrugen->folios[old_gen][type][zone];
+ unsigned long delta = 0;
while (!list_empty(head)) {
struct folio *folio = lru_to_folio(head);
+ long nr_pages = folio_nr_pages(folio);
int refs = folio_lru_refs(folio);
bool workingset = folio_test_workingset(folio);
+ bool gen_increased;
VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio);
VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio);
VM_WARN_ON_ONCE_FOLIO(folio_is_file_lru(folio) != type, folio);
VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio);
- new_gen = folio_inc_gen(lruvec, folio);
+ new_gen = __folio_inc_gen(folio, old_gen, &gen_increased);
list_move_tail(&folio->lru, &lrugen->folios[new_gen][type][zone]);
-
+ if (gen_increased)
+ delta += nr_pages;
/* don't count the workingset being lazily promoted */
if (refs + workingset != BIT(LRU_REFS_WIDTH) + 1) {
int tier = lru_tier_from_refs(refs, workingset);
- int delta = folio_nr_pages(folio);
WRITE_ONCE(lrugen->protected[hist][type][tier],
- lrugen->protected[hist][type][tier] + delta);
+ lrugen->protected[hist][type][tier] + nr_pages);
}
if (!--remaining)
- return false;
+ break;
}
+ WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone],
+ lrugen->nr_pages[old_gen][type][zone] - delta);
+ WRITE_ONCE(lrugen->nr_pages[target_gen][type][zone],
+ lrugen->nr_pages[target_gen][type][zone] + delta);
+ if (!remaining)
+ return false;
}
done:
reset_ctrl_pos(lruvec, type, true);
--
2.34.1
next prev parent reply other threads:[~2026-08-12 12:18 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 12:16 [RFC PATCH v4 00/16] mm: mglru: fix swappiness behavior Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 01/16] mm/mglru: improve readability of isolate_folios() Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 02/16] mm/mglru: improve scan_folios() exhaustion detection Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 03/16] mm/mglru: retry the same type once if isolation fails due to races Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 04/16] mm/mglru: boost swappiness responsiveness in get_type_to_scan() Barry Song (Xiaomi)
2026-08-12 12:16 ` Barry Song (Xiaomi) [this message]
2026-08-12 12:16 ` [RFC PATCH v4 06/16] mm/mglru: batch update lrugen->protected in inc_min_seq() Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 07/16] mm/mglru: enhance cold/hot inversion handling " Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 08/16] mm/mglru: exclude folios promoted by aging from protected " Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 09/16] mm/mglru: move folios from oldest gen to second-oldest gen from head to tail Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 10/16] mm/mglru: batch move folios to the second-oldest gen's LRU Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 11/16] mm/mglru: skip gentle reclaim at DEF_PRIORITY for extreme swappiness Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 12/16] mm/mglru: run aging if the preferred type has no reclaimable gens Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 13/16] mm/mglru: remove redundant gens <= MIN_NR_GENS check in should_run_aging() Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 14/16] mm/mglru: run aging when pages are severely imbalanced across gens Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 15/16] mm/mglru: dynamically scale aging threshold in lru_gen_imbalanced() Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 16/16] mm/mglru: reduce folios pulled from the oldest gen in inc_min_seq() 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=20260812121658.69965-6-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=chenridong@xiaomi.com \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=lianux.mm@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=lyugaofei@xiaomi.com \
--cc=mhocko@kernel.org \
--cc=qi.zheng@linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=stevensd@chromium.org \
--cc=wangzicheng@honor.com \
--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 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.