On Tue, Sep 01, 2026 at 12:01:21PM +0100, Lorenzo Stoakes (ARM) wrote:
> When an anonymous mapping is collapsed for THP, a PTE page table is
> 'deposited' with the installed PMD entry.
> 
> This is done in order that a split can be performed without needing to
> allocate additional memory.
> 
> The freeing occurs in zap_deposited_table() and is done directly without
> any delay via pte_free().
> 
> This is currently not a problem as existing page table walks are protected
> by the mmap or anon rmap lock.
> 
> However this becomes problematic in a future where RCU-only page table
> walkers exist, as there is nothing to prevent a page table walker that
> started the walk prior to collapse having its PTE table freed underneath
> it.
> 
> Commit 13cf577e6b66 ("mm/pgtable: add pte_free_defer() for pgtable as
> page") already provides us the mechanism by which to solve this -
> pte_free_defer().
> 
> Therefore, as a prerequisite to a future commit which will permit fully RCU
> page table walks, update zap_deposited_table() to use pte_free_defer()
> rather than pte_free().
> 
> Note that the IPI sync in collapse_huge_page() is still required to ensure
> refcount correctness against a GUP-fast operation.
> 
> This is because GUP-fast might increment refcount, but
> __collapse_huge_page_isolate() determines whether it is safe to proceed by
> checking folio_ref_count() against folio_expected_ref_count(), so the two
> must be mutually excluded.
> 
> Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
> ---
>  mm/huge_memory.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 54494c3fa983..505f7b62ff28 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -2476,7 +2476,7 @@ static inline void zap_deposited_table(struct mm_struct 
> *mm, pmd_t *pmd)
>       pgtable_t pgtable;
>  
>       pgtable = pgtable_trans_huge_withdraw(mm, pmd);
> -     pte_free(mm, pgtable);
> +     pte_free_defer(mm, pgtable);

Hm. So it is call_rcu() on each PMD. It might be costly, especially for
zap_huge_pmd() path: 512 call_rcu() per-GB of unmapped THPs.

Do we want leverage mmu_gather if caller has it?

>       mm_dec_nr_ptes(mm);
>  }
>  
> 
> -- 
> 2.55.0
> 

-- 
  Kiryl Shutsemau / Kirill A. Shutemov

Reply via email to