QEMU-KVM 内存虚拟化介绍
【摘要】 背景主要是背景以及内存相关的原理 QEMU和KVMQEMU-KVM的内存虚拟化由QEMU和KVM实现, KVM类似资源管理和提供者, QEMU类似资源的申请和使用者,同时QEMU从guestos角度来看是虚拟设备的提供者 整体业务流程:Guest启动:QEMU 从自己的进程地址空间为Guest申请内存(用户态做内存申请)QEMU调用KVM的API,将Guest的内存地址信息注册到KVM中维...
背景
主要是背景以及内存虚拟化相关的原理
QEMU和KVM
- QEMU-KVM的内存虚拟化由QEMU和KVM实现, KVM类似资源管理和提供者, QEMU类似资源的申请和使用者,同时QEMU从guestos角度来看是虚拟设备的提供者
整体业务流程:
- Guest启动:QEMU 从自己的进程地址空间为Guest申请内存(用户态做内存申请)
- QEMU调用KVM的API,将Guest的内存地址信息注册到KVM中维护 (内核态做内存管理)
- GVA-> GPA -> HVA -> HPA 的地址转换, GPA从QEMU的虚拟地址空间中分配
- 内存虚拟化主要维护GPA到HVA的映射
QEMU内存管理-SPT
- 前面说到内存虚拟化主要是维护GPA到HVA的映射, 到实现层面,需要的方式是影子页表(SPT, 由KVM维护)和EPT/NTP, 影子页表通过软件实现,ETP/NPT通过硬件时间二级映射。现在基本上都是使用硬件实现。
EPT
- 在EPT(Extended Page Table,硬件支持GPA<–>HPA)出现之前,内存虚拟化通过维护一个影子页表,VMM拦截page fault更新影子页表。
- 有了EPT以后,Guest 的缺页在 Guest OS 内部处理,不会 VM-EXIT 到 KVM 中。地址转化基本由硬件(MMU)查页表来完成,大大提升了效率,且只需为 Guest 维护一份 EPT 页表,减少内存的开销
- 如上图,在 Guest OS 运行时,Guest 对应的 EPT 地址被加载到 EPTP,而 Guest OS 当前运行的进程页表基址被加载到 CR3。于是在进行地址转换时,首先通过 CR3 指向的页表实现 GVA 到 GPA 的转换,再通过 EPTP 指向的 EPT 完成 GPA 到 HPA 的转换。当发生 EPT Page Fault 时,需要 VM-EXIT 到 KVM,更新 EPT。
整体技术栈
- kvm在整个技术栈中承担硬件操作和资源管理的角色,QEMU承担提供虚拟设备的角色。
QEMU内存数据结构
- Address Space:
- Memory Region: QEMU中有两个全局的memory region, 分别是system_memory 和system_io, 以指针的形式存在。 Memory Region负责管理Host的内存
- Flat View
- Flat Range
- Memory Region Section
- RAMList
- RAMBlock: RAMBlock ram_block才是真正分配了host内存的地方,如果把它直接理解成一个内存条也是非常合适的,但实际上不仅仅如此,还有设备自有内存,显存。它的主要元素就是mr,host, offset和used_length,size,addr,每一个ramblock都有一个对应的MemoryRegion。
- KVMSlot
- kvm_userspace_memory_region
热迁移
热迁移的机制
- 热迁移的内存复制主要有三种机制,pre-copy, post-copy, hybrid-copy. 现在的虚拟化平台基本上都是使用pre-copy的机制
迭代复制的三个原则
- 集中原则: 一个循环内的dirty pages小于等于50
- 不扩散原则: 一个循环内传输的dirty pages少于新产生的,在被迁移VM的内核设置一个内存访问的监控模块,在内存pre-copy阶段,VM的一个进程在一个被调度运行周期,被限制最多执行40次内存写操作。这个措施直接限制了pre-copy过程中内存变脏的速度
- 有限循环原则: 循环次数必须少于30, 对于每轮pre-copy的效果进行计算,如果pre-copy对于减少dirty page的效果不显著,或者循环次数超过了上限,循环会中止,进入停机拷贝阶段
迭代拷贝的6个阶段
- 热迁移主要流程是:源端和目的端建立连接,precopy模式下,开始数据的迭代拷贝,源端暂停虚机,拷贝最后一个迭代状态数据,最后在目的端启动虚机。其中迭代拷贝分为几个阶段:
定义在qemu\migration\savevm.h 中
#define QEMU_VM_EOF 0x00 //表示数据传递结束
#define QEMU_VM_SECTION_START 0x01 // 第一轮数据传递开始
#define QEMU_VM_SECTION_PART 0x02 // 迭代迁移数据中
#define QEMU_VM_SECTION_END 0x03 // VM已暂停,即将进行最后一轮迁移
#define QEMU_VM_SECTION_FULL 0x04 // 内存数据迁移完成,进行其他设备状态数据迁移
#define QEMU_VM_SUBSECTION 0x05 // 其他设备的状态迁移
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)