背景
虚拟化场景下,free page reporting 让 guest 把 buddy 中的空闲页周期性地报告给 host,host 据此取消这些页的映射(unmap),从而把物理内存归还给 host 侧其他任务。reporting 由一个 delayed work 驱动,旧实现的报告间隔硬编码为 2 * HZ(约 2 秒)。
固定 2 秒在稳定 workload 下是合理的:既较快把空闲内存归还 host,又不至于过于频繁。但在 spiky 的分配/释放波动(churn)下问题显现:guest 刚报告出去的页被 host unmap,紧接着 guest 又重新分配这些页,host 不得不重新建立嵌套页表映射,触发大量 nested page fault,反而造成性能损失。
┌──────────────────────┐
│ guest 空闲页 │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ 固定 2 秒报告给 host │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ host unmap 这些页 │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ guest 重分配已报告页 │ 触发 nested page fault
└──────────────────────┘
问题
- 报告间隔硬编码为 2HZ,无法按 guest workload 调整。
- spiky 分配释放下,激进立即报告让 host 反复 unmap 又重建映射。
- guest 重用已报告页触发大量 nested page fault,开销显著。
- 缺少在激进回收与低开销之间权衡的旋钮。
方案
把这个硬编码间隔暴露为一个可调的模块参数 page_reporting_delay_ms,单位毫秒,默认 2000(精确等于原先的 2 * HZ),默认行为完全不变,只是新增了调节能力。
它通过 module_param() 以 uint 类型导出,路径是 /sys/module/page_reporting/parameters/page_reporting_delay_ms,命名与内核变量一致。delayed work 的调度由原来的固定 PAGE_REPORTING_DELAY 改为 msecs_to_jiffies(page_reporting_delay_ms) 动态换算,覆盖 __page_reporting_request() 与 page_reporting_process() 两处调度点,并在 kernel-parameters.txt 里登记为 page_reporting.page_reporting_delay_ms= 引导参数。
管理员可按 workload 选择:内存长期闲置时调小以尽快归还 host,churn 剧烈时调大以在更长窗口内批量报告,吸收分配与释放的波动,避免 hypercall 与 re-fault 的反复开销。参数不封顶,取 0 也安全:上报只由 high-order 页释放触发,hypercall 开销进入前有 slot 容量水位检查把关。
上报间隔改为可调的模块参数
┌────────────────────────────────────────────────────┐
│ 把硬编码的 2 HZ 间隔暴露为 page_reporting_delay_ms │
│ 模块参数 │
└─────────────────────────┬──────────────────────────┘
▼
┌────────────────────────────────────────────────────┐
│ 默认 2000 毫秒与原行为一致,管理员可 │
│ 按 workload 调整 │
└─────────────────────────┬──────────────────────────┘
▼
┌────────────────────────────────────────────────────┐
│ churn 剧烈时调大在更长窗口批量上报吸 │
│ 收波动 │
└────────────────────────────────────────────────────┘
收益
作者未提供性能数据,从代码逻辑推断的预期收益:
- churn 场景下调大延迟,在更长窗口批量报告空闲页,减少 guest 重用已报告页导致的 nested page fault。
- 降低报告频次,摊薄每次报告的 hypercall 与 host 侧 re-fault 开销。
- 默认 2000ms 与原 2HZ 行为一致,无回归风险,仅在需要时按 workload 调整。
- 作为模块参数无取值上限,管理员可自由按 workload 设定上报节奏。