Re: [RFC PATCH v3 7/8] mm/gup: walk multiple PTEs per follow_page_pte() call
From: Yuan-Hao Hsu
Date: Wed Oct 14 2026 - 17:55:03 EST
On Mon, 10 Aug 2026 22:51:56 -0400, Rik van Riel wrote:
> + for (; address < walk_end; address += PAGE_SIZE, ptep++) {
> + pte_t pte = ptep_get(ptep);
> + struct page *page;
> +
> + ret = follow_one_pte(vma, address, ptep, pte, flags, &page);
> + if (!ret && page) {
> + ret = follow_page_pte_commit(vma, address,
> + page_folio(page), page,
> + pte, flags,
> + pages ? pages + nr : NULL);
> + if (!ret) {
> + nr++;
> + continue;
> + }
> + }
[...]
> + pte_unmap_unlock(orig_ptep, ptl);
follow_page_pte_commit() ends in gup_fill_pages(), so the pages[] fill
and the flush_anon_page()/flush_dcache_page() pair for every page of
the walk now run under the PTE lock: up to PTRS_PER_PTE pages per
hold, 512 on x86-64 and 8192 on arm64 with 64K pages. Before the
series that loop sat in __get_user_pages() after follow_page_mask()
had returned, with only the mmap lock held; 2/8 moved it under the
PTE lock for one page, and this patch extends it to the whole table.
5/8 moves the same work out of the pmd/pud lock, with the reasoning
in its changelog, so after the series the PTE path is the only one
flushing under a spinlock, and on arm, mips, parisc and sh both
flushes do real work.
You already mentioned on 3/8 moving the gup_fill_pages() call out of
the lock so the PUD path can share the helper; this makes it more
than a cleanup. Storing pages[] under the lock is cheap; could the
flushes move after pte_unmap_unlock() and run over pages[0..nr), the
way follow_pmd_mask() and follow_pud_mask() do it after 5/8 and the
way __get_user_pages() did it before the series? With pages == NULL
there is nothing to flush either way.
Yuan-Hao Hsu