03 内存脏页与异步 PF 机制与实现详解

03 内存脏页与异步 PF 机制与实现详解

1. dirty_ring.c — 脏页环

依赖CONFIG_HAVE_KVM_DIRTY_RING(ARM64 可选 HAVE_KVM_DIRTY_RING_ACQ_REL,弱序架构需额外内存序语义)。

动机:传统 KVM_GET_DIRTY_LOG bitmap 在大内存 VM 上 扩展性差;脏页环提供 per-vCPU 环形缓冲区,用户态增量拉取脏 GPA。

要点:

  • kvm_dirty_ring_used / soft_limit / full 控制背压;
  • kvm_reset_dirty_gfn 清除 dirty 标记;
  • kvm_cpu_dirty_log_size() 为 weak,架构可扩展保留项数。

RK3588:作 host 跑大内存 Android VM 时,若启用 dirty ring 可降低 migration/live snapshot 开销;需 QEMU 与内核 同时支持

2. pfncache.c — PFN 缓存

依赖CONFIG_HAVE_KVM_PFNCACHE

缓存 GFN→PFN 解析结果,加速 MMIO/缺页路径中重复查找。架构通过 Kconfig 声明能力;与 ARM Stage-2 页表协作在 arch 层消费。

3. async_pf.c — 异步 Page Fault

依赖CONFIG_KVM_ASYNC_PF(x86 为主;ARM 支持情况视配置)。

流程概念:

  1. Guest 触发缺页 exit;
  2. 架构可投递 异步 PF 工作项 async_pf_execute
  3. 在 host mm 中 fault-in 页面后 kvm_async_pf_completion 唤醒 guest。
1
2
3
4
static void async_pf_execute(struct work_struct *work)
{
// 在 apf->mm 中处理缺页,再通知 vcpu
}

降低 KVM_RUN 线程阻塞;对 内存大、换页频繁 的 VM 有益。

4. coalesced_mmio.c — MMIO 合并

依赖CONFIG_KVM_MMIO(ARM64 KVM select)。

问题:高频 MMIO(如 virtio 环)每次写都 VM exit 开销大。

做法:在 专用页KVM_GET_VCPU_MMAP_SIZE 含一页)维护 ring buffer,批量提交 MMIO 写,减少 exit 次数。

头文件 coalesced_mmio.h 定义环格式;kvm_main 在 MMIO bus 上注册 coalesced zone。

5. kvm_mm.h

公共 MM 辅助声明,供 dirty_ringkvm_main 共享,非独立功能模块。

6. 与 kvm_main 内存路径关系

机制 触发场景
mmu_notifier host 换出/释放 guest RAM 页
dirty ring / dirty log 迁移、增量备份
async pf guest 缺页
coalesced mmio 批量设备寄存器写

ARM64 guest RAM 映射实现在 arch/arm64/kvm/mmu.c(Stage-2 IPA)。

7. RK3588 实践

场景 建议
桌面/服务器式 VM 迁移 评估 dirty ring + QEMU 新版本
嵌入式轻量 VM 常关闭,简化路径
virtio 性能 coalesced mmio + ioeventfd(见 02 文档)

8. 小结

virt/kvm 中内存相关文件侧重 性能与可扩展性页表与 Stage-2 仍在 arch。RK3588 host 调优 virtio/MMIO 时 coalesced_mmioeventfd 通常比 dirty ring 更常触及。

文章互动

阅读 --

留言

0 条留言

正在加载留言…