[PATCH v3 3/9] mm: move anon-exclusive batch helper to rmap.h
From: Dev Jain
Date: Thu Sep 24 2026 - 09:15:34 EST
In preparation for optimizing large folio unmapping, we need to reuse
the page_anon_exclusive_batch helper in rmap.c and rmap.h and obey the
existing use in mprotect.c .
Therefore, move it from mprotect.c to rmap.h.
While at it, change return type, start_idx and max_len to unsigned long
type for future proofing against THP support at >= PUD level. Also
shorten expected_anon_exclusive -> anon_exclusive.
Signed-off-by: Dev Jain <dev.jain@xxxxxxx>
---
include/linux/rmap.h | 17 +++++++++++++++++
mm/mprotect.c | 18 +-----------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 74cca0e3c7264..62ef511a6175a 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -106,6 +106,23 @@ enum ttu_flags {
#ifdef CONFIG_MMU
+/*
+ * Get max length of consecutive PTEs pointing to PageAnonExclusive() pages or
+ * !PageAnonExclusive() pages, starting from start_idx. Caller must enforce
+ * that the PTEs point to consecutive pages of the same anon large folio.
+ */
+static __always_inline unsigned long page_anon_exclusive_batch(unsigned long start_idx,
+ unsigned long max_len, struct page *first_page, bool anon_exclusive)
+{
+ unsigned long idx;
+
+ for (idx = start_idx + 1; idx < start_idx + max_len; ++idx) {
+ if (anon_exclusive != PageAnonExclusive(first_page + idx))
+ break;
+ }
+ return idx - start_idx;
+}
+
void anon_vma_init(void); /* create anon_vma_cachep */
#ifdef CONFIG_MM_ID
diff --git a/mm/mprotect.c b/mm/mprotect.c
index a1b6d29bf0390..cb996dbd0e525 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -30,6 +30,7 @@
#include <linux/mm_inline.h>
#include <linux/pgtable.h>
#include <linux/userfaultfd_k.h>
+#include <linux/rmap.h>
#include <uapi/linux/mman.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
@@ -138,23 +139,6 @@ static __always_inline void prot_commit_flush_ptes(struct vm_area_struct *vma,
tlb_flush_pte_range(tlb, addr, nr_ptes * PAGE_SIZE);
}
-/*
- * Get max length of consecutive ptes pointing to PageAnonExclusive() pages or
- * !PageAnonExclusive() pages, starting from start_idx. Caller must enforce
- * that the ptes point to consecutive pages of the same anon large folio.
- */
-static __always_inline int page_anon_exclusive_batch(int start_idx, int max_len,
- struct page *first_page, bool expected_anon_exclusive)
-{
- int idx;
-
- for (idx = start_idx + 1; idx < start_idx + max_len; ++idx) {
- if (expected_anon_exclusive != PageAnonExclusive(first_page + idx))
- break;
- }
- return idx - start_idx;
-}
-
/*
* This function is a result of trying our very best to retain the
* "avoid the write-fault handler" optimization. In can_change_pte_writable(),
--
2.43.0