uffd-wp:unmap 也要留住写保护
uffd-wp
userfaultfd 的写保护
unmap 时要保住写保护状态
present PTE
uffd-wp marker
把 present PTE 换成 marker,写保护不丢
marker 安装 helper:只会逐 PTE 处理
批量路径遇到这种 VMA,只能整体退回
批量 unmap 的意义:一次处理一批 PTE
uffd-wp 让这条快路径断了
现状 · uffd-wp VMA 被排除在批量之外
文件 large folio
批量路径已覆盖
批量 unmap
一次处理整批
遇 uffd-wp VMA
要装写保护 marker
整体退回
逐 PTE 重来
卡点:marker 安装只支持单个 PTE
没有批量装法,批量路径只能退回
这条排除同时挡住 rmap 与 zap 两条路径
两边装 marker 都还是逐个 PTE
问题 · 两处代价
zap 路径
uffd-wp marker 同样逐 PTE 设置
大批量 zapping 提不起速
try_to_unmap_one()
到处要记着 nr_pages 是 1 还是 > 1
代码阅读负担不小
前者是性能问题,后者是认知成本
都来自「marker 只能逐个装」这一条限制
方案一 · 让 marker 安装支持批量
cond_install_uffd_wp_ptes()
helper 改名,参数从单个 PTE 变成一批
批量化先落在 zap 路径
nr_pages 从哪里来
folio_pte_batch()
或 swap_pte_batch()
批量来源算出这一批的 PTE 数
为什么可以整批装
这批 PTE 同属一类 VMA
同享 wp 状态
marker 支持与否与参数无关
于是 zap 与 rmap 两条路径都可以放开
前提是每批 PTE 的 wp 状态已经一致
方案二 · 为什么用循环
这一批是 nonpresent → nonpresent
只换标记,不换页
原先没有页,装完也没有页
用 set_pte_at() 循环
不用 set_ptes()
一批里每个 PTE 各写一次
set_ptes() 处理不了 nr_pages > 1 的 nonpresent → nonpresent
所以批量安装只能自己写循环
helper 从 mm_inline.h 挪进 memory.c
体量已经超出内联头文件的合适尺寸
方案三 · rmap 侧一起放开
folio_unmap_pte_batch() 允许 uffd-wp VMA 的文件 folio
present PTE 转成 marker,写保护保留
同一段范围不能被重复处理
已经转成 marker 的 PTE,不能再当成 present 处理一遍
保证来自 page_vma_mapped_walk
check_pte() 只对 [pfn, pfn + nr_pages) 内确有 PFN 映射的 PTE 返回真
marker PTE 底下没有 PFN,walk 自动跳过已转换的范围
直到遇见下一个 present 项
预期收益 · 作者未提供性能数据
以下均为代码逻辑推断,不是实测
uffd-wp VMA 的文件 large folio 进入批量 unmap
rmap 扫描效率对齐普通文件 folio
zap 路径批量设置 marker
大批量 zapping 收益
try_to_unmap_one() 不再按 nr_pages 特判 uffd-wp
逻辑变直
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x