Re: [PATCH 1/4] x86/mm: fix missing pgtable destructor for vmemmap tables
From: David Hildenbrand (Arm)
Date: Fri Oct 09 2026 - 16:37:29 EST
On 10/9/26 22:33, David Hildenbrand (Arm) wrote:
> On 10/8/26 09:30, Muchun Song wrote:
>> Since commit 49f599666420 ("mm: call ctor/dtor for kernel PTEs"),
>> pte_alloc_one_kernel() runs the page-table constructor for kernel PTE
>> tables.
>>
>> HugeTLB vmemmap optimization uses pte_alloc_one_kernel() when splitting
>> a PMD. Restoring the vmemmap backing pages does not collapse the PTE
>> table, so a later memory hot-remove eventually frees that table through
>> free_pagetable(). That path currently calls pagetable_free() directly
>> without decrementing NR_PAGETABLE.
>>
>> Use PageTable() to identify constructor-backed tables and run the
>> matching destructor before freeing them. Keep reserved and
>> constructor-free tables on their existing paths. This also prepares
>> vmemmap teardown for generic runtime allocations through the normal
>> pgalloc helpers.
>>
>> Fixes: 49f599666420 ("mm: call ctor/dtor for kernel PTEs")
>> Cc: stable@xxxxxxxxxxxxxxx
>> Assisted-by: LLM
>> Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
>> ---
>> arch/x86/mm/init_64.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
>> index 70e682180291..a3ea627157ab 100644
>> --- a/arch/x86/mm/init_64.c
>> +++ b/arch/x86/mm/init_64.c
>> @@ -1003,6 +1003,8 @@ static void __meminit free_pagetable(struct page *page)
>> {
>> if (PageReserved(page))
>> free_reserved_page(page);
>> + else if (PageTable(page))
>> + pagetable_dtor_free(page_ptdesc(page));
>> else
>> pagetable_free(page_ptdesc(page));
>> }
>
> pagetable_free() will do ptdesc_test_kernel(pt) -> pagetable_free_kernel(pt) ->
> pagetable_dtor_free().
Ah, behavior depends on CONFIG_ASYNC_KERNEL_PGTABLE_FREE$ ...
Why not do the right thing in pagetable_free() instead?
--
Cheers,
David