Thread (96 messages) 96 messages, 16 authors, 2025-10-09

Re: [PATCH RFC 10/35] mm/hugetlb: cleanup hugetlb_folio_init_tail_vmemmap()

From: Mike Rapoport <rppt@kernel.org>
Date: 2025-08-23 09:00:08
Also in: dri-devel, intel-gfx, io-uring, kvm, linux-arm-kernel, linux-crypto, linux-ide, linux-iommu, linux-kselftest, linux-mips, linux-mm, linux-mmc, linux-riscv, linux-s390, linux-scsi, lkml, virtualization
Subsystem: hugetlb subsystem, memory management, the rest · Maintainers: Muchun Song, Oscar Salvador, Andrew Morton, Linus Torvalds

On Fri, Aug 22, 2025 at 08:24:31AM +0200, David Hildenbrand wrote:
On 22.08.25 06:09, Mika Penttilä wrote:
quoted
On 8/21/25 23:06, David Hildenbrand wrote:
quoted
All pages were already initialized and set to PageReserved() with a
refcount of 1 by MM init code.
Just to be sure, how is this working with MEMBLOCK_RSRV_NOINIT, where MM is supposed not to
initialize struct pages?
Excellent point, I did not know about that one.

Spotting that we don't do the same for the head page made me assume that
it's just a misuse of __init_single_page().

But the nasty thing is that we use memblock_reserved_mark_noinit() to only
mark the tail pages ...
And even nastier thing is that when CONFIG_DEFERRED_STRUCT_PAGE_INIT is
disabled struct pages are initialized regardless of
memblock_reserved_mark_noinit().

I think this patch should go in before your updates:
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 753f99b4c718..1c51788339a5 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3230,6 +3230,22 @@ int __alloc_bootmem_huge_page(struct hstate *h, int nid)
 	return 1;
 }
 
+/*
+ * Tail pages in a huge folio allocated from memblock are marked as 'noinit',
+ * which means that when CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled their
+ * struct page won't be initialized
+ */
+#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
+static void __init hugetlb_init_tail_page(struct page *page, unsigned long pfn,
+					enum zone_type zone, int nid)
+{
+	__init_single_page(page, pfn, zone, nid);
+}
+#else
+static inline void hugetlb_init_tail_page(struct page *page, unsigned long pfn,
+					enum zone_type zone, int nid) {}
+#endif
+
 /* Initialize [start_page:end_page_number] tail struct pages of a hugepage */
 static void __init hugetlb_folio_init_tail_vmemmap(struct folio *folio,
 					unsigned long start_page_number,
@@ -3244,7 +3260,7 @@ static void __init hugetlb_folio_init_tail_vmemmap(struct folio *folio,
 	for (pfn = head_pfn + start_page_number; pfn < end_pfn; pfn++) {
 		struct page *page = pfn_to_page(pfn);
 
-		__init_single_page(page, pfn, zone, nid);
+		hugetlb_init_tail_page(page, pfn, zone, nid);
 		prep_compound_tail((struct page *)folio, pfn - head_pfn);
 		ret = page_ref_freeze(page, 1);
 		VM_BUG_ON(!ret);
 
Let me revert back to __init_single_page() and add a big fat comment why
this is required.

Thanks!
-- 
Sincerely yours,
Mike.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help