From: Muchun Song <songmuchun@bytedance.com>
To: Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Oscar Salvador <osalvador@suse.de>,
Madhavan Srinivasan <maddy@linux.ibm.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Jonathan Corbet <corbet@lwn.net>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-doc@vger.kernel.org,
Muchun Song <muchun.song@linux.dev>,
Lorenzo Stoakes <ljs@kernel.org>, Mike Rapoport <rppt@kernel.org>,
Qi Zheng <qi.zheng@linux.dev>,
Nicholas Piggin <npiggin@gmail.com>,
Christophe Leroy <chleroy@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Muchun Song <songmuchun@bytedance.com>
Subject: [PATCH v3 07/11] mm/sparse-vmemmap: move vmemmap optimization helpers to a public header
Date: Fri, 11 Sep 2026 13:02:24 +0800 [thread overview]
Message-ID: <20260911050228.58884-8-songmuchun@bytedance.com> (raw)
In-Reply-To: <20260911050228.58884-1-songmuchun@bytedance.com>
The vmemmap optimization helpers currently live in mm/sparse.h,
which is an internal MM header. That works for MM code, but
prevents powerpc from using the same interfaces without including a
private header.
Move the declarations and inline helpers to
include/linux/vmemmap-optimization.h. This is a preparatory change for
powerpc, which has its own vmemmap optimization implementation and needs
to use the common vmemmap optimization interfaces from architecture code.
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Qi Zheng <qi.zheng@linux.dev>
---
v3:
- Update the subject and commit message to describe common vmemmap
optimization helpers
- Collect Acked-by from Qi Zheng
v2:
- Fix missing header dependencies.
---
MAINTAINERS | 1 +
include/linux/vmemmap-optimization.h | 94 ++++++++++++++++++++++++++++
mm/hugetlb.c | 2 +-
mm/hugetlb_vmemmap.c | 2 +-
mm/sparse.h | 76 +---------------------
5 files changed, 98 insertions(+), 77 deletions(-)
create mode 100644 include/linux/vmemmap-optimization.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 3ef018673b5e..e4412c3d8d45 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12096,6 +12096,7 @@ F: Documentation/mm/hugetlbfs_reserv.rst
F: Documentation/mm/vmemmap_dedup.rst
F: fs/hugetlbfs/
F: include/linux/hugetlb.h
+F: include/linux/vmemmap-optimization.h
F: include/trace/events/hugetlbfs.h
F: mm/hugetlb.c
F: mm/hugetlb_cgroup.c
diff --git a/include/linux/vmemmap-optimization.h b/include/linux/vmemmap-optimization.h
new file mode 100644
index 000000000000..2327929467f3
--- /dev/null
+++ b/include/linux/vmemmap-optimization.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * vmemmap-optimization.h
+ *
+ * Generic vmemmap optimization declarations.
+ *
+ * Author: Muchun Song <songmuchun@bytedance.com>
+ */
+#ifndef _LINUX_VMEMMAP_OPTIMIZATION_H
+#define _LINUX_VMEMMAP_OPTIMIZATION_H
+
+#include <linux/align.h>
+#include <linux/log2.h>
+#include <linux/mmdebug.h>
+#include <linux/mmzone.h>
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
+static inline unsigned int section_compound_order(const struct mem_section *section)
+{
+ return section->compound_page_order;
+}
+
+static inline void section_set_compound_order(struct mem_section *section,
+ unsigned int order)
+{
+ VM_WARN_ON(section_compound_order(section) && order &&
+ section_compound_order(section) != order);
+ section->compound_page_order = order;
+}
+
+static inline void section_set_compound_order_range(unsigned long pfn,
+ unsigned long nr_pages, unsigned int order)
+{
+ unsigned long section_nr = pfn_to_section_nr(pfn);
+
+ if (!IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))
+ return;
+
+ for (unsigned long i = 0; i < nr_pages / PAGES_PER_SECTION; i++)
+ section_set_compound_order(__nr_to_section(section_nr + i), order);
+}
+
+static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
+{
+ return section_compound_order(__pfn_to_section(pfn));
+}
+#else
+static inline unsigned int section_compound_order(const struct mem_section *section)
+{
+ return 0;
+}
+
+static inline void section_set_compound_order(struct mem_section *section,
+ unsigned int order)
+{
+}
+
+static inline void section_set_compound_order_range(unsigned long pfn,
+ unsigned long nr_pages, unsigned int order)
+{
+}
+
+static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
+{
+ return 0;
+}
+#endif /* CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION */
+
+static inline bool vmemmap_optimizable_pfn(unsigned long pfn)
+{
+ const unsigned int order = pfn_to_section_compound_order(pfn);
+ const unsigned long nr_pages = 1UL << order;
+
+ if (!is_power_of_2(sizeof(struct page)))
+ return false;
+
+ return (pfn & (nr_pages - 1)) >= VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES;
+}
+
+static inline bool vmemmap_optimizable_order(unsigned int order)
+{
+ if (!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION))
+ return false;
+
+ if (!is_power_of_2(sizeof(struct page)))
+ return false;
+
+ return order >= VMEMMAP_OPTIMIZATION_MIN_ORDER;
+}
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+struct page *vmemmap_shared_tail_page(unsigned int order, struct zone *zone);
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+#endif /* _LINUX_VMEMMAP_OPTIMIZATION_H */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 0d101ef934fc..7af55e1544e9 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -38,6 +38,7 @@
#include <linux/mm_inline.h>
#include <linux/padata.h>
#include <linux/pgalloc.h>
+#include <linux/vmemmap-optimization.h>
#include <asm/page.h>
#include <asm/tlb.h>
@@ -52,7 +53,6 @@
#include "hugetlb_cma.h"
#include "hugetlb_internal.h"
#include "mm_init.h"
-#include "sparse.h"
#include <linux/page-isolation.h>
#define HUGE_BOOTMEM_ZONES_VALID BIT(0)
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 5ddf06b83c96..a27f46fffb54 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -15,10 +15,10 @@
#include <linux/mmdebug.h>
#include <linux/pagewalk.h>
#include <linux/pgalloc.h>
+#include <linux/vmemmap-optimization.h>
#include <asm/tlbflush.h>
#include "hugetlb_vmemmap.h"
-#include "sparse.h"
#include "internal.h"
/**
diff --git a/mm/sparse.h b/mm/sparse.h
index a250bea4088e..a5111087ee3a 100644
--- a/mm/sparse.h
+++ b/mm/sparse.h
@@ -9,80 +9,7 @@
#define __MM_SPARSE_H
#include <linux/mmzone.h>
-
-#ifdef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
-static inline unsigned int section_compound_order(const struct mem_section *section)
-{
- return section->compound_page_order;
-}
-
-static inline void section_set_compound_order(struct mem_section *section,
- unsigned int order)
-{
- VM_WARN_ON(section_compound_order(section) && order &&
- section_compound_order(section) != order);
- section->compound_page_order = order;
-}
-
-static inline void section_set_compound_order_range(unsigned long pfn,
- unsigned long nr_pages, unsigned int order)
-{
- unsigned long section_nr = pfn_to_section_nr(pfn);
-
- if (!IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))
- return;
-
- for (unsigned long i = 0; i < nr_pages / PAGES_PER_SECTION; i++)
- section_set_compound_order(__nr_to_section(section_nr + i), order);
-}
-
-static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
-{
- return section_compound_order(__pfn_to_section(pfn));
-}
-#else
-static inline unsigned int section_compound_order(const struct mem_section *section)
-{
- return 0;
-}
-
-static inline void section_set_compound_order(struct mem_section *section,
- unsigned int order)
-{
-}
-
-static inline void section_set_compound_order_range(unsigned long pfn,
- unsigned long nr_pages, unsigned int order)
-{
-}
-
-static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
-{
- return 0;
-}
-#endif
-
-static inline bool vmemmap_optimizable_pfn(unsigned long pfn)
-{
- const unsigned int order = pfn_to_section_compound_order(pfn);
- const unsigned long nr_pages = 1UL << order;
-
- if (!is_power_of_2(sizeof(struct page)))
- return false;
-
- return (pfn & (nr_pages - 1)) >= VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES;
-}
-
-static inline bool vmemmap_optimizable_order(unsigned int order)
-{
- if (!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION))
- return false;
-
- if (!is_power_of_2(sizeof(struct page)))
- return false;
-
- return order >= VMEMMAP_OPTIMIZATION_MIN_ORDER;
-}
+#include <linux/vmemmap-optimization.h>
/*
* mm/sparse.c
@@ -142,7 +69,6 @@ static inline void sparse_sections_init(void) {}
* mm/sparse-vmemmap.c
*/
#ifdef CONFIG_SPARSEMEM_VMEMMAP
-struct page *vmemmap_shared_tail_page(unsigned int order, struct zone *zone);
void sparse_init_subsection_map(void);
int section_nr_vmemmap_pages(unsigned long pfn, unsigned long nr_pages,
struct vmem_altmap *altmap, struct dev_pagemap *pgmap);
--
2.54.0
next prev parent reply other threads:[~2026-09-11 5:04 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 5:02 [PATCH v3 00/11] mm: Switch device DAX to section-based vmemmap optimization Muchun Song
2026-09-11 5:02 ` [PATCH v3 01/11] mm/sparse-vmemmap: introduce CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION Muchun Song
2026-09-11 5:02 ` [PATCH v3 02/11] mm/sparse-vmemmap: factor out shared vmemmap tail page allocation Muchun Song
2026-09-11 5:02 ` [PATCH v3 03/11] mm/sparse-vmemmap: open-code init_compound_tail() Muchun Song
2026-09-11 5:02 ` [PATCH v3 04/11] mm/sparse-vmemmap: prepare DAX vmemmap population for compound page orders Muchun Song
2026-09-11 5:02 ` [PATCH v3 05/11] mm/sparse-vmemmap: set compound page order for device DAX Muchun Song
2026-09-11 5:02 ` [PATCH v3 06/11] mm/sparse-vmemmap: switch device DAX to shared tail vmemmap pages Muchun Song
2026-09-11 5:02 ` Muchun Song [this message]
2026-09-11 5:02 ` [PATCH v3 08/11] powerpc/mm: " Muchun Song
2026-09-11 5:02 ` [PATCH v3 09/11] mm/sparse-vmemmap: drop the extra tail page from device DAX reservation Muchun Song
2026-09-11 5:02 ` [PATCH v3 10/11] mm/sparse-vmemmap: drop unused section_nr_vmemmap_pages() arguments Muchun Song
2026-09-11 5:02 ` [PATCH v3 11/11] Documentation/mm: update DAX vmemmap deduplication docs Muchun Song
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=20260911050228.58884-8-songmuchun@bytedance.com \
--to=songmuchun@bytedance.com \
--cc=akpm@linux-foundation.org \
--cc=chleroy@kernel.org \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=ljs@kernel.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=muchun.song@linux.dev \
--cc=npiggin@gmail.com \
--cc=osalvador@suse.de \
--cc=qi.zheng@linux.dev \
--cc=rdunlap@infradead.org \
--cc=rppt@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox