[PATCH v7 9/9] mm: always use the zone-device template init path

From: Li Zhe

Date: Mon Jul 20 2026 - 08:09:08 EST


The template path still has a local opt-out predicate for the
page_ref_set tracepoint and keeps a non-template fallback path. This
makes the code more complex without a strong reason to keep the
separate path.

Use the template path unconditionally after the corresponding seed page
has been initialized: the first head page seeds the head template, and
the first tail page in each compound range seeds the tail template.

This keeps the first-page seeding logic unchanged, but removes the extra
non-template fallback from the main loops.

This also means sanitized builds no longer force this path back to the
per-page initialization stores, and an enabled page_ref_set tracepoint
will no longer observe every ZONE_DEVICE initialization-time refcount
assignment. That tradeoff is intentional: this code is still initializing
struct pages before they are handed out, and keeping those local debug
special cases would preserve a separate initialization-only path while
making the common code more complex.

Suggested-by: Muchun Song <muchun.song@xxxxxxxxx>
Signed-off-by: Li Zhe <lizhe.67@xxxxxxxxxxxxx>
---
mm/mm_init.c | 36 ++++--------------------------------
1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 2a723a518f41..ae42a1311e1d 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1065,25 +1065,6 @@ static void __ref zone_device_page_init_slow(struct page *page,
set_page_count(page, 0);
}

-static inline bool zone_device_page_init_optimization_enabled(void)
-{
- /*
- * Keep sanitized builds on the slow path so their stores stay
- * instrumented.
- */
- if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_KMSAN))
- return false;
-
- /*
- * The template fast path copies a preinitialized struct page image.
- * Skip it when the page_ref_set tracepoint is enabled.
- */
- if (page_ref_tracepoint_active(page_ref_set))
- return false;
-
- return true;
-}
-
static inline void zone_device_tail_page_init(struct page *page,
unsigned long pfn, unsigned long zone_idx, int nid,
struct dev_pagemap *pgmap, const struct page *head,
@@ -1151,8 +1132,7 @@ static void __ref memmap_init_compound(struct page *head,
unsigned long head_pfn,
unsigned long zone_idx, int nid,
struct dev_pagemap *pgmap,
- unsigned long nr_pages,
- bool use_template)
+ unsigned long nr_pages)
{
unsigned long pfn, end_pfn = head_pfn + nr_pages;
unsigned int order = pgmap->vmemmap_shift;
@@ -1169,10 +1149,7 @@ static void __ref memmap_init_compound(struct page *head,
for (pfn = head_pfn + 1; pfn < end_pfn; pfn++) {
struct page *page = pfn_to_page(pfn);

- if (!use_template) {
- zone_device_tail_page_init(page, pfn, zone_idx, nid,
- pgmap, head, order);
- } else if (pfn == head_pfn + 1) {
+ if (pfn == head_pfn + 1) {
/*
* All tails of the same compound page share the
* state established by prep_compound_tail(). Reuse
@@ -1197,7 +1174,6 @@ void __ref memmap_init_zone_device(struct zone *zone,
unsigned long nr_pages,
struct dev_pagemap *pgmap)
{
- bool use_template = zone_device_page_init_optimization_enabled();
unsigned long pfn, end_pfn = start_pfn + nr_pages;
struct pglist_data *pgdat = zone->zone_pgdat;
struct vmem_altmap *altmap = pgmap_altmap(pgmap);
@@ -1223,10 +1199,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
for (pfn = start_pfn; pfn < end_pfn; pfn += pfns_per_compound) {
struct page *page = pfn_to_page(pfn);

- if (!use_template) {
- zone_device_page_init_slow(page, pfn, zone_idx,
- nid, pgmap);
- } else if (pfn == start_pfn) {
+ if (pfn == start_pfn) {
/*
* Seed the reusable head-page template from the
* first real struct page, because the existing
@@ -1249,8 +1222,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
continue;

memmap_init_compound(page, pfn, zone_idx, nid, pgmap,
- compound_nr_pages(pfn, altmap, pgmap),
- use_template);
+ compound_nr_pages(pfn, altmap, pgmap));
}

pageblock_migratetype_init_range(start_pfn, nr_pages, MIGRATE_MOVABLE);
--
2.20.1