2021
https://kvm-forum.qemu.org/2021/
KVM Memory Cost Optimization in Alibaba Cloud - Huaitong Han
主要是 rmap 在使用大页时候的优化,但是这个工作并没有进:
我感觉主要的原因是,rmap 可以直接被去掉,他这里只是优化 rmap 在 guest 虚拟机使用 2M 大页的情况
2026-02-21 kimi 分析的,我感觉很正确:
1. Page Tracking (gfn_write_track) 延迟分配 - ✅ 已实现
关键代码位置: arch/x86/kvm/mmu/page_track.c
// 第 60-68 行:创建 memslot 时的延迟分配逻辑
int kvm_page_track_create_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot,
unsigned long npages)
{
// 只有在 write tracking 启用时才分配内存
if (!kvm_page_track_write_tracking_enabled(kvm))
return 0; // 直接返回,不分配内存
return __kvm_page_track_write_tracking_alloc(slot, npages);
}
启用条件判断 (第 36-40 行):
bool kvm_page_track_write_tracking_enabled(struct kvm *kvm)
{
return kvm_external_write_tracking_enabled(kvm) ||
kvm_shadow_root_allocated(kvm) || !tdp_enabled;
}
结论: 对于使用 EPT (tdp_enabled=true) 且没有分配 shadow root 的 VM,gfn_write_track 不会在创建 memslot 时分配内存,实现了延迟分配优化。
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2. Rmap 内存优化 - ⚠️ 部分实现
当前实现: arch/x86/kvm/x86.c (第 13381-13401 行)
int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages)
{
const int sz = sizeof(*slot->arch.rmap[0]);
int i;
// 为所有页大小级别分配 rmap:4K, 2M, 1G
for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
int level = i + 1;
int lpages = __kvm_mmu_slot_lpages(slot, npages, level);
if (slot->arch.rmap[i])
continue;
slot->arch.rmap[i] = __vcalloc(lpages, sz, GFP_KERNEL_ACCOUNT);
// ...
}
}
数据结构定义: arch/x86/include/asm/kvm_host.h (第 1098-1102 行)
struct kvm_arch_memory_slot {
struct kvm_rmap_head *rmap[KVM_NR_PAGE_SIZES]; // 3 个级别: 4K, 2M, 1G
struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
unsigned short *gfn_write_track;
};
TDP MMU 已移除 Rmap 依赖
代码位置: arch/x86/kvm/mmu/tdp_mmu.c
当前内核已实现 TDP MMU (Two-Dimensional Paging MMU),它不使用 rmap 结构。当 tdp_mmu_enabled 为 true 时,KVM 使用 TDP MMU 而不是传统的基于 rmap 的 MMU。
证据:
• tdp_mmu.c 中没有使用 slot->arch.rmap
• TDP MMU 使用独立的页表遍历机制 (tdp_iter.c)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
3. 延迟分配触发点
Rmap 和 Page Track 的延迟分配发生在 arch/x86/kvm/mmu/mmu.c (第 4030-4050 行):
// 当需要启用 shadow paging 时,才分配 rmap 和 page track
if (!kvm_memslots_have_rmaps(kvm) && !tdp_mmu_enabled) {
r = memslot_rmap_alloc(slot, slot->npages);
if (r)
goto out_unlock;
r = kvm_page_track_write_tracking_alloc(slot);
if (r)
goto out_unlock;
}
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
总结
优化项 状态 说明
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
gfn_write_track 延迟分配 ✅ 已实现 EPT VM 默认不分配,需要时才分配
rmap 分级分配优化 ⚠️ 部分实现 传统 MMU 仍为所有级别分配;TDP MMU 完全不使用 rmap
TDP MMU 替代方案 ✅ 已实现 上游已用 TDP MMU 替代传统 rmap 方案
PDF 中提到的 rmap 结构优化(只为实际使用的 hugepage 级别分配 rmap)在当前代码中未完全实现,但 TDP MMU 已成为主流方案,它彻底移除了 rmap 的依赖,从根本
上解决了内存开销问题。
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。