exec 文件缺页
VM_EXEC 文件映射
filemap_fault 走同步预读
do_sync_mmap_readahead()
large folio 的价值
一次预读更多页
减少缺页与预读往返
指令 TLB 更友好
arm64 可 contpte
arm64 64K 的麻烦
HPAGE_PMD_ORDER = 13
即 512MB PMD
MAX_PAGECACHE_ORDER = 11
fault_around_pages = 1
两条约束
mmap_miss 误套到 exec
PMD 阶硬门槛挡住大基页
mmap_miss 投机节流
每文件维护的 mmap_miss
MMAP_LOTSAMISS = 100
缓存命中才递减
exec 预读并不投机
受 VMA 边界约束
exec_folio_order()
async_size = 0
VM_HUGEPAGE 是显式 opt-in
fault_around 失效后
fault_around_pages = 1
filemap_map_pages 到不了
计数只增不减
mmap_miss > 100 就禁用
后果
exec 预读被永久掐断
large folio 阶也一起失效
force_thp_readahead
VM_HUGEPAGE 强制路径
旧门槛:PMD 阶 <= 页缓存上限
请求写死 HPAGE_PMD_ORDER
arm64 64K
HPAGE_PMD_ORDER = 13
512MB PMD
MAX_PAGECACHE_ORDER = 11
门槛不成立
退回基页
normal mmap readahead
只按基页读入
iTLB 未命中高
哪怕映射支持大 folio
第二道
PMD 阶硬门槛
把大基页配置挡在门外
修复一 · 绕过计数
if (!(vm_flags & (VM_SEQ_READ | VM_EXEC)))
do_sync_mmap_readahead()
不再 increment / 不再查阈值
递减也跳过
do_async_mmap_readahead()
filemap_map_pages()
两个递减点同样跳过
增减保持对称
为什么安全
新增跳过 VM_EXEC
VM_SEQ_READ 已有先例
不再累积 stale throttle
exec 预读恢复
效果
不再被 mmap_miss 掐断
exec_folio_order 重新可用
修复二 · 改门槛
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)
&& (vm_flags & VM_HUGEPAGE)
&& mapping_large_folio_support(mapping)
请求映射支持的阶
thp_order = min_t(unsigned int,
mapping_max_folio_order(mapping),
get_order(SZ_2M))
上限 2M
按阶预读
folio_nr_pages = 1UL << thp_order
ra->size = folio_nr_pages
ra->order = thp_order
page_cache_ra_order()
边界
非 RAND_READ 时 size 再乘 2
最终阶仍被 page_cache_ra_order 钳制
为什么是 2M
x86_64 PMD = 2M
arm64 4K PMD = 2M
大小 / 内存压力已有共识
arm64 大基页
16K / 64K base page
contpte 块 = 2M
folio 合并进一个 TLB 项
预读路径 TLB 压力下降
不是越大越好
16K 基页不再预读 32M folio
contpte 下差异可忽略
更高阶增加内存压力
2M 是折中
最终
mapping 支持 + 请求几何
仍会钳制阶
基准环境
Neoverse V2 (Grace)
arm64 64K base page
512MB exec / ext4 / 3 次平均
负载
mmap 大可执行文件
madvise huge
PAGE_SIZE 偏移调 RET-stub
Cold / Random 两阶段
测什么
Cold:缺页 + 预读
Random:先顺序 fault(不计)
再随机偏移执行
隔离 iTLB 未命中
目的
Cold 看预读开销
Random 看分散执行 iTLB
结果 · 作者 benchmark
Cold 83.4 → 41.3 ms
Random 76.0 → 58.3 ms
3 次平均
Cold fault
缺页 + 预读开销
一次搬入更多页
减少缺页与往返
快约 50%
Random
隔离 iTLB 未命中
更多指令落进 large folio
iTLB 未命中减少
快约 23%
边界
仅 Grace / arm64 64K / ext4
不承诺所有工作负载
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x