From: Baoquan He <baoquan.he@linux.dev>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, kasong@tencent.com, baohua@kernel.org,
qi.zheng@linux.dev, shakeel.butt@linux.dev,
axelrasmussen@google.com, yuanchu@google.com, weixugc@google.com,
Baoquan He <baoquan.he@linux.dev>
Subject: [PATCH 4/4] mm/mglru: invalidate empty-walk skip on page fault and migration
Date: Fri, 7 Aug 2026 17:23:41 +0800 [thread overview]
Message-ID: <20260807092343.4123734-4-baoquan.he@linux.dev> (raw)
In-Reply-To: <20260807092343.4123734-1-baoquan.he@linux.dev>
empty_map skips an mm on a node for up to K generations after an empty
walk, leaving a window where pages that appear on that node are not aged
until the forced rescan. Notify MGLRU when a page of the mm appears:
set the node's bitmap bit and clear its empty_map bit. Fault and
migration are both software events, so the invalidation is complete - a
node marked empty has no pages there, so a page can only appear via a
fault or a migration.
- mm/memory.c do_anonymous_page()/finish_fault(): mark the folio's node
after the page is allocated (anon and file/COW faults).
- mm/migrate.c remove_migration_pte(): mark the folio's destination node
(also covers NUMA-balancing migration).
The bitmap bit is mostly redundant with schedule-time marking, but is
needed when migration targets an idle mm whose bits were already
cleared by a previous walk.
Signed-off-by: Baoquan He <baoquan.he@linux.dev>
---
include/linux/mm_types.h | 18 ++++++++++++++++++
mm/memory.c | 7 +++++++
mm/migrate.c | 3 +++
3 files changed, 28 insertions(+)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 68ec8bb2ab71..89b723483675 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1531,6 +1531,20 @@ static inline void lru_gen_use_mm(struct mm_struct *mm)
WRITE_ONCE(mm->lru_gen.bitmap, -1);
}
+/*
+ * A page of this mm appeared on (or was accessed on) node @nid â e.g. a page
+ * fault or a migration. Set that node's bitmap bit so the aging walker walks
+ * the mm, and clear the empty-walk skip so a page that just appeared on a node
+ * previously marked empty is not ignored for up to K generations.
+ */
+static inline void lru_gen_mm_accessed(struct mm_struct *mm, int nid)
+{
+ unsigned long key = nid % BITS_PER_TYPE(mm->lru_gen.bitmap);
+
+ set_bit(key, &mm->lru_gen.bitmap);
+ clear_bit(key, &mm->lru_gen.empty_map);
+}
+
#else /* !CONFIG_LRU_GEN_WALKS_MMU */
static inline void lru_gen_add_mm(struct mm_struct *mm)
@@ -1553,6 +1567,10 @@ static inline void lru_gen_use_mm(struct mm_struct *mm)
{
}
+static inline void lru_gen_mm_accessed(struct mm_struct *mm, int nid)
+{
+}
+
#endif /* CONFIG_LRU_GEN_WALKS_MMU */
struct vma_iterator {
diff --git a/mm/memory.c b/mm/memory.c
index 428eb555ecb7..e3d7c8f7ca7d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -5512,6 +5512,9 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
folio_put(folio);
return handle_userfault(vmf, VM_UFFD_MISSING);
}
+ /* a new page of this mm lands on this node: invalidate any empty skip */
+ lru_gen_mm_accessed(vma->vm_mm, folio_nid(folio));
+
map_anon_folio_pte_pf(folio, vmf->pte, vma, addr,
vmf_orig_pte_uffd_wp(vmf));
unlock:
@@ -5772,6 +5775,10 @@ vm_fault_t finish_fault(struct vm_fault *vmf)
page = vmf->page;
folio = page_folio(page);
+
+ /* mapping a page of this mm on this node: invalidate any empty skip */
+ lru_gen_mm_accessed(vma->vm_mm, folio_nid(folio));
+
/*
* check even for read faults because we might have lost our CoWed
* page
diff --git a/mm/migrate.c b/mm/migrate.c
index b937cbd76480..2e0674e89ba8 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -354,6 +354,9 @@ static bool remove_migration_pte(struct folio *folio,
struct rmap_walk_arg *rmap_walk_arg = arg;
DEFINE_FOLIO_VMA_WALK(pvmw, rmap_walk_arg->folio, vma, addr, PVMW_SYNC | PVMW_MIGRATION);
+ /* the folio ends up on folio_nid(): notify MGLRU for this mm */
+ lru_gen_mm_accessed(vma->vm_mm, folio_nid(folio));
+
while (page_vma_mapped_walk(&pvmw)) {
rmap_t rmap_flags = RMAP_NONE;
pte_t old_pte;
--
2.54.0
prev parent reply other threads:[~2026-08-07 9:24 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 10:29 [RFC PATCH 0/6] mm/mglru: skip empty PUD subtrees during aging with PUD-level Bloom filter Baoquan He
2026-08-06 10:29 ` [RFC PATCH 1/6] mm/mglru: add PUD-level Bloom filter state Baoquan He
2026-08-06 10:29 ` [RFC PATCH 2/6] mm/mglru: refactor Bloom filter helpers for two filter levels Baoquan He
2026-08-06 10:29 ` [RFC PATCH 3/6] mm/mglru: skip empty PUD subtrees during aging Baoquan He
2026-08-06 10:29 ` [RFC PATCH 4/6] mm/mglru: report hot PUDs from the rmap feedback path Baoquan He
2026-08-06 10:29 ` [RFC PATCH 5/6] mm/mglru: add MM_WALK_EMPTY stats and tracepoint for cross-node measurement Baoquan He
2026-08-06 11:05 ` [RFC PATCH 0/6] mm/mglru: skip empty PUD subtrees during aging with PUD-level Bloom filter Baoquan He
2026-08-07 9:23 ` [PATCH 1/4] mm/mglru: add MM_WALK_EMPTY stats and tracepoint for cross-node measurement Baoquan He
2026-08-07 9:23 ` [PATCH 2/4] mm/mglru: suppress cross-node empty page table walks Baoquan He
2026-08-07 9:23 ` [PATCH 3/4] mm/mglru: add debugfs knob to control cross-node empty walk skip threshold Baoquan He
2026-08-07 9:23 ` Baoquan He [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=20260807092343.4123734-4-baoquan.he@linux.dev \
--to=baoquan.he@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=kasong@tencent.com \
--cc=linux-mm@kvack.org \
--cc=qi.zheng@linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=weixugc@google.com \
--cc=yuanchu@google.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.