folio_walk_start(9)
โจ folio_walk_start(9) โจ
okay bestie so this one lives in the Kernel API Manual and it's literally about walking the page tables to a folio ๐ฆ buckle up, it's giving very-much-internals.
๐ธ NAME ๐ธ
folio_walk_start โ walk the page tables to a folio ๐
โจ SYNOPSIS โจ
struct folio * folio_walk_start (struct folio_walk *fw , struct
vm_area_struct *vma , unsigned long addr , folio_walk_flags_t flags );
๐ ARGUMENTS ๐
fwโ gets filled with all the info on success ๐vmaโ the VMA. that's the vibe check zone you're walking in.addrโ the virtual address you wanna use for the page table walk.flagsโ the flags that modify which folios we walk to ๐ง
๐ฅ DESCRIPTION ๐ฅ
So what it does: it walks the page tables using addr inside a given vma, all the way to a mapped folio, and returns that folio ๐ซถ and while it's doing that it makes sure the page table entry referenced by addr cannot change until folio_walk_end was called. no cap, that's the whole safety vibe.
By default โ like, out of the box โ this function returns only folios that are not special (e.g., not the zeropage), and it never returns folios that are supposed to be ignored by the VM as documented by vm_normal_page. But if you request it with the flags, zeropages will get returned as well ๐
If this function returns NULL it could mean either "there is nothing" or "there is nothing suitable" โ yeah ๐ญ it's one of those two, the call is not gonna tell you which one, that's just how it is.
On success, fw is filled and the function returns the folio while the PTL is still held, and folio_walk_end must be called to clean up, releasing any held locks ๐. The returned folio must *not* be used after the call to folio_walk_end, unless you take a short-term folio reference before that call. periodt.
fw->page will correspond to the page that is effectively referenced by addr. However โ and this is the little plot twist ๐ โ for shared zeropages, fw->page is set to NULL. Also note that large folios might be mapped by multiple page table entries, and this function will always only look up a single entry as specified by addr, which might or might not cover more than a single page of the returned folio. so like, don't assume, bestie.
๐จ hard no: this function must *not* be used as a naive replacement forget_user_pages/pin_user_pages, especially not to perform DMA or to carelessly modify page content. This function may *only* be used to grab short-term folio references โ never to grab long-term folio references. ๐
Using the page table entry pointers in fw for reading or modifying the entry should be avoided where possible โ however, there might be valid use cases ๐ซก
โ ๏ธ WARNING: modifying page table entries in hugetlb VMAs requires a lot of care. For example, PMD page table sharing might require prior unsharing. Also, logical hugetlb entries might span multiple physical page table entries, which *must* be modified in a single operation (set_huge_pte_at,huge_ptep_set_*, ...). Note that the page table entry stored infwmight not correspond to the first physical entry of a logical hugetlb entry. ๐ฎโ๐จ iykyk.
And the vibe check: the mmap lock must be held in read mode. non-negotiable ๐
โญ RETURN โญ
folio pointer on success, otherwise NULL ๐
๐ SEE ALSO ๐
- Kernel file
./mm/pagewalk.c walk_page_range(9)walk_kernel_page_table_range(9)walk_page_range_debug(9)walk_page_mapping(9)
and that's the whole page, bestie ๐ it comes from ./mm and it's dated October 2026 โ slay, go read the source, mwah ๐โจ
๐ฆ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms