[PATCH 3/7] mm/migrate: copy the referenced state via folio_migrate_refs()
Kairui Song via B4 Relay <devnull+kasong.tencent.com-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
| Newsgroups | gmane.linux.kernel.cgroups,gmane.linux.kernel.mm,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Kairui Song <[email protected]> folio_migrate_flags() copies PG_referenced separately, while folio_migrate_refs() copies the rest of the reference state. Make folio_migrate_refs() copy the complete state, i.e., PG_referenced plus the MGLRU refs counter, in both LRU implementations, and drop the open-coded copy so the reference state is transferred in one place. Signed-off-by: Kairui Song <[email protected]> --- include/linux/mm_inline.h | 16 +++++++++++++--- mm/migrate.c | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 93bf3fa221f8..df62daaa2ee7 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -366,11 +366,19 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, return true; } +/** + * folio_migrate_refs - copy the reference state to a new folio + * @new: the destination folio + * @old: the source folio + * + * Transfer the reference state to @new during migration: the MGLRU + * refs count, including PG_referenced, or just PG_referenced for the + * active/inactive LRU. + */ static inline void folio_migrate_refs(struct folio *new, const struct folio *old) { - unsigned long refs = READ_ONCE(old->flags.f) & LRU_REFS_MASK; - - set_mask_bits(&new->flags.f, LRU_REFS_MASK, refs); + BUILD_BUG_ON(LRU_REFS_MASK & BIT(PG_referenced)); + folio_set_lru_refs(new, folio_lru_refs(old)); } #else /* !CONFIG_LRU_GEN */ @@ -401,6 +409,8 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, static inline void folio_migrate_refs(struct folio *new, const struct folio *old) { + if (folio_test_referenced(old)) + folio_set_referenced(new); } #endif /* CONFIG_LRU_GEN */ diff --git a/mm/migrate.c b/mm/migrate.c index 15b45832bcfa..82307332711f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -776,8 +776,6 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio) { int cpupid; - if (folio_test_referenced(folio)) - folio_set_referenced(newfolio); if (folio_test_uptodate(folio)) folio_mark_uptodate(newfolio); if (folio_test_clear_active(folio)) { @@ -807,7 +805,9 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio) if (folio_test_idle(folio)) folio_set_idle(newfolio); + /* Copy the reference state, including PG_referenced */ folio_migrate_refs(newfolio, folio); + /* * Copy NUMA information to the new page, to prevent over-eager * future migrations of this same page. -- 2.55.0