On Fri, Aug 22, 2025 at 08:24:31AM +0200, David Hildenbrand wrote:
On 22.08.25 06:09, Mika Penttilä wrote:
On 8/21/25 23:06, David Hildenbrand wrote:
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!