[PATCH RFC v2 06/15] mm/mglru: move add/del LRU size accounting out of lru_gen_update_size()

From: Kairui Song via B4 Relay

Date: Fri Sep 11 2026 - 08:19:46 EST


From: Kairui Song <kasong@xxxxxxxxxxx>

Pure code shuffle, no behavior change. lru_gen_update_size() now only
updates the per-generation counters plus the promotion move; the
addition and deletion active/inactive accounting move to
lru_gen_add_folio() and lru_gen_del_folio(), which know the generation
and can apply the active-window test directly.

The unevictable case is untouched: unevictable folios never enter
lru_gen_add_folio() and keep being accounted by lruvec_add_folio() as
before.

Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
---
include/linux/mm_inline.h | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 5a62b83b4168..8700563dade8 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -298,21 +298,9 @@ static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *foli
if (new_gen >= 0)
atomic_long_add(delta, &lrugen->nr_pages[new_gen][type][zone]);

- /* addition */
- if (old_gen < 0) {
- if (lru_gen_is_active(lruvec, new_gen))
- lru += LRU_ACTIVE;
- __update_lru_size(lruvec, lru, zone, delta);
+ /* return now if not a promotion */
+ if (old_gen < 0 || new_gen < 0)
return;
- }
-
- /* deletion */
- if (new_gen < 0) {
- if (lru_gen_is_active(lruvec, old_gen))
- lru += LRU_ACTIVE;
- __update_lru_size(lruvec, lru, zone, -delta);
- return;
- }

/* promotion */
if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) {
@@ -366,6 +354,8 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
int gen = folio_lru_gen(folio);
int type = folio_is_file_lru(folio);
int zone = folio_zonenum(folio);
+ int delta = folio_nr_pages(folio);
+ enum lru_list lru = type * LRU_INACTIVE_FILE;
struct lru_gen_folio *lrugen = &lruvec->lrugen;

BUILD_BUG_ON(BIT(LRU_GEN_WIDTH - 1) != MAX_NR_GENS);
@@ -381,6 +371,10 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
set_mask_bits(folio_flags(folio, 0), LRU_GEN_MASK | BIT(PG_active), flags);

lru_gen_update_size(lruvec, folio, -1, gen);
+ if (lru_gen_is_active(lruvec, gen))
+ lru += LRU_ACTIVE;
+ __update_lru_size(lruvec, lru, zone, delta);
+
/* for folio_rotate_reclaimable() */
if (reclaiming)
list_add_tail(&folio->lru, &lrugen->folios[gen][type][zone]);
@@ -394,6 +388,9 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
{
unsigned long flags;
int gen = folio_lru_gen(folio);
+ int zone = folio_zonenum(folio);
+ int delta = folio_nr_pages(folio);
+ enum lru_list lru = folio_is_file_lru(folio) * LRU_INACTIVE_FILE;

if (gen < 0)
return false;
@@ -407,6 +404,9 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;

lru_gen_update_size(lruvec, folio, gen, -1);
+ if (lru_gen_is_active(lruvec, gen))
+ lru += LRU_ACTIVE;
+ __update_lru_size(lruvec, lru, zone, -delta);
list_del(&folio->lru);

return true;

--
2.55.0