背景
大页的 tail struct page 内容完全相同,vmemmap 优化(HVO)让它们的 vmemmap PTE 指向同一个共享物理页,从而释放掉其余 vmemmap 物理页。HugeTLB 先行系列已把这套优化改为 section-based:compound order 记入 mem_section,sparse-vmemmap population 路径按 section 元数据分配或复用共享 tail 页。
device DAX 仍沿用旧的 DAX 专用模型:vmemmap_populate_compound_pages() 为每个 compound 区域显式分配 head 与 first tail 两个 vmemmap 物理页,其余 tail 映射复用 first tail 页;powerpc radix 路径还有一套自己走页表查找可复用尾页的逻辑。
旧 DAX 模型与 section-based 模型
┌────────────────────────────────────────┐ ┌───────────────────────────────────────────┐
│ 旧 DAX 模型每个区域预留 head 与 first │ │ section-based 模型把 order 记进 section, │
│ tail 两页,其余 tail 复用 first tail, ├──▶│ population 按元数据共享 per-zone │
│ powerpc 还自行查页表找复用页 │ │ tail 页 │
└────────────────────────────────────────┘ └───────────────────────────────────────────┘
问题
- device DAX 沿用 DAX 专用填充模型,与 section-based 基础设施两套并存
- 每个 compound 区域在 head 外多预留 1 个 first tail vmemmap 页
- powerpc radix 自行走页表找可复用尾页,与通用逻辑重复
方案
把 device DAX 切到 HugeTLB 已引入的 section-based sparse-vmemmap 基础设施,让 DAX 与 HugeTLB 共用同一套优化路径。
切换分 3 步推进。
第 1 步把优化决策依据换成 section 元数据:填充 vmemmap 之前把 pgmap->vmemmap_shift 写进 section order,之后 vmemmap 记账与 population 都直接查 section,不再依赖 pgmap 参数回推。只有整个 section 被同一 compound 几何填满才可优化,向已优化 section 的部分添加被拒绝;section 清空时 order 随之清掉。
第 2 步把 tail 映射换到 per-zone 共享 tail 页(vmemmap_shared_tail_page()),与 HugeTLB 同一个;共享页为 device zone 的 struct page 标上 PG_reserved,内存移除时跳过对这些 section 的 poisoning,因为其中的 struct page 可能是共享页。共享 tail 页被每个映射它的 PTE 各拿一次引用,映射范围足够大时引用计数有溢出回绕的风险,拿引用因此改用 try_get_page(),到上限时填充直接失败,并回滚该 section 已建立的映射。
第 3 步去掉 DAX 专属的额外预留:共享 tail 页覆盖 head 之后的所有 tail vmemmap 页,预留从 head 加 first tail 两页减为 head 一页。
device DAX 的切换路径
┌────────────────────────────────────────┐
│ 填充前把 compound order 写进 section, │
│ 整 section 同几何才可优化 │
└───────────────────┬────────────────────┘
▼
┌────────────────────────────────────────┐
│ 换用 per-zone 共享 tail 页,powerpc │
│ 删掉自己的页表查找 │
└───────────────────┬────────────────────┘
▼
┌────────────────────────────────────────┐
│ 去掉 head 外的额外 tail 预留,预留从 │
│ 两页减为一页 │
└────────────────────────────────────────┘
powerpc radix 路径同步切换:原来自行从页表逐级查找可复用尾页并带回退的逻辑整体删除,改用同一个共享 tail 页 helper,与通用路径同构。配套改动包括把 HugeTLB 时期的 HVO helper 移到公共头文件、把配置符号通用化为 CONFIG_VMEMMAP_OPTIMIZATION。本系列是「Generalize HVO for HugeTLB and device DAX」拆出的第 3 个子系列,HugeTLB 与 device DAX 之间进一步的合并留给后续。
收益
作者未提供性能数据,从代码逻辑推断的预期收益:
- 每个可优化 compound 区域的 vmemmap 预留从 2 页减到 1 页
- DAX 与 HugeTLB 共用一套 section-based 路径,DAX 专用填充模型删除
- powerpc radix 删除专用尾页查找与回退,与通用路径同构
- section 元数据成为唯一决策依据,为后续 HVO 通用化合并铺路