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 00/16] mm: mglru: fix swappiness behavior
Date: Wed, 12 Aug 2026 20:16:42 +0800 [thread overview]
Message-ID: <20260812121658.69965-1-baohua@kernel.org> (raw)
The active/inactive LRU respects swappiness well. Anonymous page
scanning and reclamation increase roughly linearly with swappiness,
while file page scanning and reclamation decrease accordingly.
For example, with extreme swappiness values such as 1, the
active/inactive LRU performs much more file reclaim, while at 200 it
performs much more anonymous reclaim with little or even no file
reclaim.
In contrast, MGLRU shows little change across different swappiness
values, especially at the extremes of 1 and 200.
The data below was collected while building the kernel in a 1 GB
MEMCG with -j20 and zRAM configured as swap.
pgsteal_file
Swappiness LRU MGLRU
--------------------------------
1 10788341 760931
36 1101082 526479
71 683084 406540
106 465165 380845
141 292018 361058
176 207810 332329
200 0 349617
pgsteal_anon
Swappiness LRU MGLRU
--------------------------------
1 4305108 2594416
36 2790004 2984411
71 2692223 2965396
106 2844429 3039293
141 3101425 3087067
176 3394419 3110359
200 13210927 3080592
pgscan_file
Swappiness LRU MGLRU
--------------------------------
1 18718146 887478
36 1485019 610943
71 849670 460520
106 561680 433057
141 368688 404839
176 234273 375214
200 0 400190
pgscan_anon
Swappiness LRU MGLRU
--------------------------------
1 29683174 6008050
36 27142699 5960053
71 25804052 6278323
106 26582642 6416301
141 28199275 6349025
176 29360048 6277269
200 62517850 6295609
refault_file
Swappiness LRU MGLRU
--------------------------------
1 10693128 587183
36 1018405 343244
71 602508 247697
106 388580 224246
141 216110 200426
176 127306 175176
200 0 189009
refault_anon
Swappiness LRU MGLRU
--------------------------------
1 593074 540688
36 231609 654679
71 263264 642920
106 286477 640700
141 331410 634729
176 390750 656967
200 4120283 642881
This patchset respects the type selected by get_type_to_scan(),
which uses swappiness as its gain. It does so by running aging when
the preferred type has few or no reclaimable folios, allowing more
folios of that type to become reclaimable.
As we begin to respect swappiness more strictly, inc_min_seq()
may be called more frequently. While this function resolves cold/hot
inversion issues, it may itself introduce additional cold/hot
inversions, which are addressed by this patchset. In addition, we use
batching where possible to reduce the overhead of inc_min_seq().
Patches 1–3 improve readability and enhance the exhausted checks in
isolate_folios() and scan_folios().
Patch 4 increases the impact of swappiness on type selection.
Patches 5–10 fix potential cold/hot inversions and use batching where
possible to improve the performance of inc_min_seq().
Patches 11–15 improve should_run_aging() with additional generation
and imbalance checks, particularly when few folios remain in the
reclaimable generations.
Patch 16 reduces the batch size when moving folios from the oldest
generation to the second-oldest generation in inc_min_seq() to reduce
lock contention.
With this patchset, swappiness starts to behave more like it does
with the active/inactive LRU.
pgsteal_file
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 10788341 760931 1974207
36 1101082 526479 620248
71 683084 406540 414207
106 465165 380845 365887
141 292018 361058 335876
176 207810 332329 306476
200 0 349617 10569
pgsteal_anon
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 4305108 2594416 3204425
36 2790004 2984411 2895280
71 2692223 2965396 2766936
106 2844429 3039293 3105011
141 3101425 3087067 2989129
176 3394419 3110359 3183651
200 13210927 3080592 13354629
pgscan_file
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 18718146 887478 2753870
36 1485019 610943 712969
71 849670 460520 471135
106 561680 433057 419504
141 368688 404839 374698
176 234273 375214 340775
200 0 400190 10880
pgscan_anon
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 29683174 6008050 5645754
36 27142699 5960053 6056810
71 25804052 6278323 5877296
106 26582642 6416301 6397449
141 28199275 6349025 5951263
176 29360048 6277269 6076458
200 62517850 6295609 21506939
refault_file
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 10693128 587183 1836987
36 1018405 343244 443893
71 602508 247697 245171
106 388580 224246 202345
141 216110 200426 178638
176 127306 175176 141618
200 0 189009 5003
refault_anon
Swappiness LRU MGLRU MGLRU+Patch
-------------------------------------------------
1 593074 540688 800149
36 231609 654679 609397
71 263264 642920 582514
106 286477 640700 653094
141 331410 634729 636040
176 390750 656967 667461
200 4120283 642881 4126464
It could be brought even closer to the active/inactive LRU by
ignoring the potential cost of inc_min_seq() and allowing more
aggressive aging. For now, however, we aim to balance the benefits of
respecting swappiness against the overall system time. Across almost
all swappiness levels, the kernel build workload shows that MGLRU with
the patch achieves lower system and wall-clock times than the
active/inactive LRU.
sys time
Swappiness LRU MGLRU+Patch
---------------------------------------
1 7m42.831s 6m15.160s
36 4m51.991s 3m42.020s
71 4m29.953s 3m39.259s
106 4m34.790s 3m48.321s
141 4m43.026s 3m42.552s
176 4m54.383s 3m46.840s
200 8m11.063s 7m28.910s
wall time
## Swappiness LRU MGLRU+Patch
1 3m08.386s 2m01.631s
36 1m54.989s 1m49.887s
71 1m52.556s 1m48.879s
106 1m51.885s 1m49.942s
141 1m52.143s 1m48.916s
176 1m51.925s 1m48.703s
200 2m02.300s 2m00.487s
RFC v4:
* Clean up isolate_folios() based on Baolin's feedback. Thanks!
* Further improve isolate_folios() and scan_folios(), including
handling of exhausted reclaim types.
* Add fixes and performance improvements to inc_min_seq(),
and reduce lock contention.
* Improve the handling of imbalanced aging and remaining
generation-based aging.
* RFC v3 link:
https://lore.kernel.org/linux-mm/20260731083843.37811-1-baohua@kernel.org/
RFC v3:
- Added Ridong's patch of improving isolate_folios() readability;
- for lru_gen_imbalanced(), apply some suggestions from Zicheng
and Kairui, considering lruvec size and use macro;
- drop "mm: mglru: only fall back when reclaim is running at high
priority"
- mitigate aging for balanced swappiess value(near middle 100)
as swappiness bias is less a concern for them; but slightly
increased aging overhead might not be good.
* RFC v2 link:
https://lore.kernel.org/linux-mm/20260726122123.7614-1-baohua@kernel.org/
RFC v2:
- Quickly address a few issues raised in the Sashiko comments so
reviewers can ignore v1 and review a cleaner version instead.
https://sashiko.dev/#/patchset/20260726012946.18684-1-baohua@kernel.org
Thanks, Sashiko!
Barry Song (Xiaomi) (13):
mm/mglru: improve scan_folios() exhaustion detection
mm/mglru: retry the same type once if isolation fails due to races
mm/mglru: boost swappiness responsiveness in get_type_to_scan()
mm/mglru: batch update lrugen->nr_pages in inc_min_seq()
mm/mglru: batch update lrugen->protected in inc_min_seq()
mm/mglru: enhance cold/hot inversion handling in inc_min_seq()
mm/mglru: exclude folios promoted by aging from protected in
inc_min_seq()
mm/mglru: move folios from oldest gen to second-oldest gen from head
to tail
mm/mglru: batch move folios to the second-oldest gen's LRU
mm/mglru: skip gentle reclaim at DEF_PRIORITY for extreme swappiness
mm/mglru: run aging if the preferred type has no reclaimable gens
mm/mglru: dynamically scale aging threshold in lru_gen_imbalanced()
mm/mglru: reduce folios pulled from the oldest gen in inc_min_seq()
Bo Zhang (1):
mm/mglru: remove redundant gens <= MIN_NR_GENS check in
should_run_aging()
Ridong Chen (1):
mm/mglru: improve readability of isolate_folios()
lyugaofei (1):
mm/mglru: run aging when pages are severely imbalanced across gens
mm/vmscan.c | 289 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 233 insertions(+), 56 deletions(-)
--
2.34.1
next 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 Barry Song (Xiaomi) [this message]
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 ` [RFC PATCH v4 05/16] mm/mglru: batch update lrugen->nr_pages in inc_min_seq() Barry Song (Xiaomi)
2026-08-12 12:16 ` [RFC PATCH v4 06/16] mm/mglru: batch update lrugen->protected " 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-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=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.