v4 2026-09-29

拆分 collapse 引擎与调用者 · v4

v4 重构 khugepaged/collapse 接口,分离折叠引擎与调用者,移除 is_khugepaged 相关分支。

原始补丁链接

子 Patch(13)

1/13
mm/khugepaged: drop redundant mm_struct pin in madvise_collapse()
madvise_collapse() 中的 mmgrab()/mmdrop() 冗余:madvise、process_madvise(经 mm_access())、io_uring、DAMON(经 get_task_mm())四个调用方都已持 mm_users 引用,可安全删除。
2/13
mm/khugepaged: count collapses where khugepaged makes them
khugepaged_pages_collapsed 原在共享的 collapse_single_pmd() 里靠 cc->is_khugepaged 判断后累加;改由守护进程在自己的结果处理处计数,共享路径不再需要探知调用者是谁。
3/13
mm/khugepaged: rename mthp_present_ptes bitmap to eligible_ptes
mthp_present_ptes 置位实际表示 PTE 已通过 uffd、lazyfree、匿名与共享检查,是可用的 collapse 源,且 mthp_collapse() 从 PMD order 起读取,故重命名为 eligible_ptes,纯改名。
4/13
mm/collapse: add collapse.h for the collapse interface
新建 mm/collapse.h 承载折叠引擎与使用方的共享接口,把 enum scan_result、struct collapse_control 及两个上限常量从 khugepaged.c 移出并去掉 KHUGEPAGED_ 前缀,为后续拆分铺垫,无功能变化。
5/13
mm/collapse: state what a collapse may do in the policy
把折叠路径中散落的 cc->is_khugepaged 判断收敛为 struct collapse_policy,由调用方填好:khugepaged 依自身设置,MADV_COLLAPSE 依用户显式请求;PTE 上限分 PMD 与 sub-PMD 两套,删掉 is_khugepaged。
6/13
mm/collapse: drop the collapse_possible() wrapper
collapse_possible() 仅把 collapse_possible_orders() 返回的掩码转成 bool,三个调用方本可直接测试掩码,删除这层包装,无功能变化。
7/13
mm/collapse: name the per-table scan reset for what it resets
collapse_control_init_scan() 实际是在每张 PTE 表扫描前重置 node load、分配 nodemask 和 eligible-PTE 位图,而非初始化整个 control,故改名为 collapse_scan_reset(),为引入真正的 init/release 铺路,无功能变化。
8/13
mm/collapse: call collapse_file() from collapse_single_pmd()
把 collapse_file() 调用从 collapse_scan_file() 上移到 collapse_single_pmd(),使扫描只停在决策点;写回重试不再重扫,mm_khugepaged_scan_file 在折叠前上报 SCAN_SUCCEED,为拆出无 mmap_lock 的执行阶段做准备。
9/13
mm/collapse: separate scanning a PTE table from collapsing it
把 collapse_single_pmd() 拆成 collapse_scan_pmd()(持锁扫表决策,匿名分支保留为 collapse_scan_anon_pmd())与 collapse_run_pmd()(放锁后按 SCAN_SUCCEED / SCAN_PTE_MAPPED_HUGEPAGE 执行分配与拷贝),为锁分离铺路。
10/13
mm/collapse: open-code collapse_single_pmd() in its two callers
在两个调用方展开 collapse_single_pmd():各自持锁扫描,发现可折叠先放 mmap_lock 再执行,删去 khugepaged 的 lock_dropped 与 madvise_collapse() 的 mmap_unlocked,让 scan 持锁进持锁出、run 无锁。
11/13
mm/collapse: work out the orders a VMA allows once per VMA
把 collapse_possible_orders() 由每张 PTE 表调用改为每个 VMA 算一次并传入掩码;锁释放后掩码即失效,故 madvise_collapse() 每次折叠后重算,hugepage_vma_revalidate() 仍会再校验 order。
12/13
mm/collapse: declare the collapse interface in collapse.h
在 collapse.h 中声明 collapse_control_init()/scan_pmd()/run_pmd()、collapse_possible_orders() 和由 hugepage_vma_revalidate() 改名的 collapse_vma_revalidate(),补 kerneldoc 说明每步锁状态,供 madvise.c 复用,无功能变化。
13/13
mm/collapse: implement MADV_COLLAPSE in madvise.c
把 MADV_COLLAPSE 的范围遍历、逐 PMD 循环与 errno 映射从 khugepaged.c 迁到 madvise.c,改以 struct madvise_behavior 携带范围、VMA 与放锁标志,仍复用同一 collapse 接口,折叠行为不变。