Re: [PATCH] mm/khugepaged: free unused page table when setting a huge PMD fails

From: David Hildenbrand (Arm)

Date: Thu Nov 05 2026 - 11:50:04 EST


On 11/5/26 14:04, Kiryl Shutsemau wrote:
> On Thu, Nov 05, 2026 at 01:02:08PM +0000, Kiryl Shutsemau wrote:
>> On Thu, Nov 05, 2026 at 01:16:05PM +0100, David Hildenbrand (Arm) wrote:
>>> do_set_pmd() can allocate vmf.prealloc_pte on architectures that need a
>>> deposited page table, such as PowerPC with the hash MMU. If the PMD is
>>> no longer empty when it takes the PMD lock, it returns VM_FAULT_FALLBACK
>>> without consuming that table.
>>>
>>> Since collapse_pte_mapped_thp() uses mmap_read_lock(), a concurrent
>>> userfaultfd operation can install a PTE table before taking the folio
>>> lock. If that races with set_huge_pmd(), the unused preallocated table
>>> is lost when its local vm_fault goes out of scope.
>>>
>>> Free vmf.prealloc_pte on failure, as do_fault() already does. Successful
>>> PMD installation consumes the table and clears the pointer.
>>>
>>> Having to do this cleanup outside of do_set_pmd() is rather nasty, but
>>> other callers depend on it already having been allocated. This needs a
>>> cleanup at some point.
>>
>> I hate this being outside of do_set_pmd().
>>
>> What about making do_set_pmd() freeing ->prealloc_pte if it was
>> allocated inside? Nothing changes for caller.
>
> Or if we want to keep in set_huge_pmd() then set_huge_pmd() has to
> allocate it too. At least, it makes some sense.

It's all rather nasty.

I thought the callers depend on it, but if we just free in the function
it will behave the same way independent of arch_needs_pgtable_deposit(),
so that makes sense.