Skip to the content.

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 将按侵权追究法律责任,其它情况随意。