Re: [PATCH 06/10] x86/mm: stop marking page tables as MIX_SECTION_INFO

From: David Hildenbrand (Arm)

Date: Wed Jul 08 2026 - 11:57:35 EST


On 7/8/26 16:11, David Hildenbrand (Arm) wrote:
> There is no good reason to mark boot page tables as MIX_SECTION_INFO: we
> only free boot page tables when they are completely empty, and memory
> offlining/hotunplug doesn't benefit from it in any way.
>
> So just stop marking page tables as MIX_SECTION_INFO. In
> free_pagetable(), we can now simply free reserved pages directly.
>
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
> ---
> arch/x86/mm/init_64.c | 59 ++-------------------------------------------------
> 1 file changed, 2 insertions(+), 57 deletions(-)
>
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index 82bb0384b8ab0..1b17dcf781e66 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1002,21 +1002,10 @@ int arch_add_memory(int nid, u64 start, u64 size,
>
> static void __meminit free_pagetable(struct page *page)
> {
> - /* bootmem page has reserved flag */
> - if (PageReserved(page)) {
> -#ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE
> - enum bootmem_type type = bootmem_type(page);
> -
> - if (type == MIX_SECTION_INFO)
> - put_page_bootmem(page);
> - else
> - free_reserved_page(page);
> -#else
> + if (PageReserved(page))
> free_reserved_page(page);
> -#endif
> - } else {
> + else
> pagetable_free(page_ptdesc(page));
> - }
> }
>
> static void __meminit free_vmemmap_pages(struct page *page, unsigned int order,
> @@ -1579,50 +1568,6 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> void register_page_bootmem_memmap(unsigned long section_nr,
> struct page *start_page, unsigned long nr_pages)
> {
> - unsigned long addr = (unsigned long)start_page;
> - unsigned long end = (unsigned long)(start_page + nr_pages);
> - unsigned long next;
> - pgd_t *pgd;
> - p4d_t *p4d;
> - pud_t *pud;
> - pmd_t *pmd;
> -
> - for (; addr < end; addr = next) {
> - pgd = pgd_offset_k(addr);
> - if (pgd_none(*pgd)) {
> - next = (addr + PAGE_SIZE) & PAGE_MASK;
> - continue;
> - }
> - get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> -
> - p4d = p4d_offset(pgd, addr);
> - if (p4d_none(*p4d)) {
> - next = (addr + PAGE_SIZE) & PAGE_MASK;
> - continue;
> - }
> - get_page_bootmem(section_nr, p4d_page(*p4d), MIX_SECTION_INFO);
> -
> - pud = pud_offset(p4d, addr);
> - if (pud_none(*pud)) {
> - next = (addr + PAGE_SIZE) & PAGE_MASK;
> - continue;
> - }
> - get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> -
> - pmd = pmd_offset(pud, addr);
> - if (pmd_none(*pmd)) {
> - next = (addr + PAGE_SIZE) & PAGE_MASK;
> - continue;
> - }
> -
> - if (!boot_cpu_has(X86_FEATURE_PSE) || !pmd_leaf(*pmd)) {
> - next = (addr + PAGE_SIZE) & PAGE_MASK;
> - get_page_bootmem(section_nr, pmd_page(*pmd),
> - MIX_SECTION_INFO);
> - } else {
> - next = pmd_addr_end(addr, end);
> - }
> - }
> }
> #endif
>
>

Sashiko being rather useless:

New issues:
- [Low] The patch leaves the entire bootmem_info infrastructure as dead code
without removing it.

-> It's not aware of other patches in the series? Surprising.


Pre-existing issues:
- [High] Kernel page table pages and vmemmap pages are freed to the buddy
allocator before their parent entries are cleared and before the TLB is flushed,
creating a dangling pointer window.

-> Reported two times in previous patches and I will not fix that.


--
Cheers,

David