folio_walk_start(9)

๐Ÿ“ฆ version 7.3.1, in nixpkgs unstable

โœจ 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 for get_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 in fw might 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 ๐ŸŒˆ


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