STRUCT MM_WALK_OPS(9)
β¨ struct mm_walk_ops(9) β Kernel API Manual, but make it make sense β¨
okay bestie, so this page is literally the <rainbow>struct mm_walk_ops</rainbow> page β it's the one in the Kernel API Manual and it's all about the callback vibes for walk_page_range. it's giving "directory of who to call when the walker hits each level of the page tables" and ngl it eats π
πΈ NAME πΈ
struct mm_walk_ops β literally the callbacks for walk_page_range. that's it, that's the whole mood π«Ά
β¨ SYNOPSIS β¨
bestie, here's the whole struct, copied exactly so we don't get it twisted:
struct mm_walk_ops {
int (*pgd_entry)(pgd_t *pgd, unsigned long addr, unsigned long next,
struct mm_walk *walk);
int (*p4d_entry)(p4d_t *p4d, unsigned long addr, unsigned long next,
struct mm_walk *walk);
int (*pud_entry)(pud_t *pud, unsigned long addr, unsigned long next,
struct mm_walk *walk);
int (*pmd_entry)(pmd_t *pmd, unsigned long addr, unsigned long next,
struct mm_walk *walk);
int (*pte_entry)(pte_t *pte, unsigned long addr, unsigned long next,
struct mm_walk *walk);
int (*pte_hole)(unsigned long addr, unsigned long next, int depth,
struct mm_walk *walk);
int (*hugetlb_entry)(pte_t *pte, unsigned long hmask, unsigned long
addr, unsigned long next, struct mm_walk *walk);
int (*test_walk)(unsigned long addr, unsigned long next, struct
mm_walk *walk);
int (*pre_vma)(unsigned long start, unsigned long end, struct
mm_walk *walk);
void (*post_vma)(struct mm_walk *walk);
int (*install_pte)(unsigned long addr, unsigned long next, pte_t
*ptep, struct mm_walk *walk);
enum page_walk_lock walk_lock;
};
π Members π
okay so every single one of these, in order, no skips, we are NOT skipping the boring parts (there are no boring parts, iykyk):
pgd_entryβ if you set it, it gets called for each non-empty PGD (top-level) entry. main character of the levels fr πp4d_entryβ if set, called for each non-empty P4D entry. slay.pud_entryβ if set, called for each non-empty PUD entry. yup, we're going all the way down πpmd_entryβ if set, called for each non-empty PMD entry, and heads up bestie: this handler is required to be able to handlepmd_trans_hugepmds. they may simply choose tosplit_huge_pageinstead of handling it explicitly. so like, you can't just ghost the THPs, you gotta have a plan πpte_entryβ if set, called for each PTE (lowest-level) entry including empty ones, except ifinstall_pteis set. and ifinstall_pteis set,pte_entryis called only for existing PTEs. very much a "depends on the situation" vibe.pte_holeβ if set, called for each hole at all levels.depthis-1if not known, and otherwise0:PGD,1:P4D,2:PUD,3:PMD. any folded depths (wherePTRS_PER_P?Dis equal to 1) are skipped. also! ifinstall_pteis specified, this will not trigger for any populated ranges. so many little conditions but we keep them all πhugetlb_entryβ if set, called for each hugetlb entry. this hook function is called with the vma lock held, in order to protect against a concurrent freeing of thepte_t*or the ptl. in some cases, the hook function needs to drop and retake the vma lock in order to avoid deadlocks while calling other functions. and in such cases the hook function must either refrain from accessing the pte or ptl after dropping the vma lock, or else revalidate those items after re-acquiring the vma lock and before accessing them. read that part twice bestie, that's a real lock-discipline moment, no cap π₯test_walkβ a caller-specific callback function to determine whether we walk over the current vma or not. the return values are literally the whole personality of this one:- returning
0means"do page table walk over the current vma" - returning a negative value means
"abort current page table walk right now" - returning
1means"skip the current vma"
- returning
and quick note: this callback is not called when the caller passes in a single VMA, as for walk_page_vma.
pre_vmaβ if set, called before starting walk on a non-null vma. like a little pre-game πpost_vmaβ if set, called after a walk on a non-null vma, provided thatpre_vmaand the vma walk succeeded. conditional queen β¨install_pteβ if set, missing page table entries are installed and thus all levels are always walked in the specified range. this callback is then invoked at the PTE level (having split any THP pages prior), providing the PTE to install. if allocations fail, the walk is aborted. this operation is only available for userland memory. Not usable for hugetlb ranges. (say it with me: not usable for hugetlb ranges π«Ά)walk_lockβ the lock setting for the walk, typed asenum page_walk_lock. it's a member, it's here, it's iconic.
π Description π
okay so the p?d_entry callbacks are called even if those levels are folded on a particular architecture/configuration. so even when the level is literally folded away, the callback still goes off. that's the whole point of the note. don't come for me, that's what it says π
π¦ SEE ALSO π¦
- Kernel file
./include/linux/pagewalk.hβstruct mm_walk(9) struct folio_walk(9)
lowkey your takeaway, bestie: this struct is a call list for the page table walk, every callback is optional but each one has rules, and the hugetlb_entry lock stuff is the part where you slow down and read π
π that's the whole page!! source lives at ./include/linux, dated October 2026, and it's filed under struct mm_walk_ops(9). periodt πβ¨
π¦ 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