v1
2026-11-03
follow_page_mask 批量返回页 · v1
重构 GUP 的 follow_page_mask(),批量处理连续同 folio 的 PTE,减少重复页表遍历和引用计数抓取。
原始补丁链接
子 Patch(8)
1/8
mm/gup: break out gup_fill_pages() helper
__get_user_pages() fills pages[] and flushes each page’s caches in an open-coded loop. Move it into a gup_fill_pages() helper, which the follow_page_mask() call chain can then use to fill its own pag
2/8
mm/gup: convert follow_page_mask() to return a long
follow_page_mask() and its helpers return a struct page pointer: NULL, ERR_PTR(), or the page found. Change the return type to long instead: 0, a negative errno, or 1 with the page stored in a new pag
3/8
mm/gup: split out folio grab-and-store helper
follow_page_pte() does two things once it has resolved a present PTE to a page: run the per-PTE safety checks (write-fault, unshare), then grab a folio reference and hand the page back: fault it in if
4/8
mm/gup: break out gup_lookup_pte() helper
follow_page_pte() is 92 lines and does two separate things: work out which page a PTE maps, if any, and commit to the page it found. The first half reaches the second through five exit paths, two of w
5/8
mm/gup: fill the pages array outside the pud/pmd lock
follow_huge_pud() and follow_huge_pmd() fill pages[] and flush the page’s caches while still holding the pud or pmd lock. Neither flush_anon_page() nor flush_dcache_page() needs that lock. Have the h
6/8
mm/gup: return a huge page's full count from follow_page_mask()
follow_huge_pud()/follow_huge_pmd() already know the huge page’s full size but report it via a separate *page_mask output; __get_user_pages() does a second try_grab_folio() call and subpage loop for e
7/8
mm/gup: walk multiple PTEs per follow_page_pte() call
follow_page_pte() looks at one PTE per call, so __get_user_pages() calls it once per page, restarting the pgd/p4d/pud/pmd descent and retaking the PTE lock each time. Walk every PTE from @address to
8/8
mm/gup: batch contiguous same-folio PTEs into one refcount grab
follow_page_pte() now walks a whole page table in one call, but still resolves and commits each PTE on its own, so a PTE-mapped large folio (mTHP) pays one try_grab_folio() per subpage. Add gup_pte_b