IO虚拟化是计算机虚拟化最复杂的部分,因为涉及到CPU、操作系统、Hypervisor以及IO设备的相互配合。IO虚拟化也经历了从软件模拟虚拟化、类虚拟化向完全硬件虚拟化的转变。
IO设备虚拟化场景,既要关注IO设备模拟,也要关注vCPU和虚拟IO设备的交互,许多条件交织在一起,使得整个问题变的非常复杂。IO虚拟化性能代价主要体现在三个方面:驱动访问设备寄存器的代价;设备通过中断和DMA访问驱动的代价;设备模拟本身的代价。因此,IO虚拟化性能优化主要是通过五个角度:
如图 3.30(a),虚拟机中看到的设备,一般是由Hypervisor模拟出来的。虚拟设备的功能,可以少于也可以多于物理的设备,甚至可以模拟出一些不存在的特性,模拟出不存在的硬件设备。通过IO软件模拟的方式,我们称之为IO设备软件模拟虚拟化。在IO软件模拟虚拟化的解决方案中,客户机VM要使用底层的硬件资源,需要Hypervisor来截获每一条请求指令,然后模拟出这些指令的行为。我们都知道Hypervisor截获指令的动作就是从VM-exit,处理完模拟然后再VM-entry的过程,这个过程的代价很高,每条指令都要如此,带来的性能开销必然是非常庞大的。
如图 3.30(b)所示,Virtio提供的类虚拟化方式,客户机完成设备的前端驱动程序,Hypervisor配合客户机完成相应的后端驱动程序,这样两者之间通过交互机制就可以实现高效的虚拟化过程。
图 3.30 IO设备虚拟化
Virtio框架如图 3.31所示,使用Virtqueue来实现其IO机制,每个Virtqueue就是一个承载大量数据的Queue。VRing是Virtqueue的具体实现方式,针对VRing会有相应的描述符表格进行描述。Virtio是一个通用的驱动和设备接口框架,基于Virtio分别实现了Virtio-net、Virtio-blk、Virtio-scsi等很多不同类型的模拟设备及设备驱动。
图 3.31 Virtio框架
Virtio类虚拟化比传统的IO设备软件模拟的性能优势体现在:很多控制和状态信息不需要通过寄存器读写操作来交互的,而是通过写入Virtqueue的相关数据结构来让驱动(Driver)和设备(Device)双方交互。并且在数据交互的时候,只需要在一定批量数据变化需要对方处理的时候才会通知对方,驱动通知设备是通过写Kick寄存器,设备通知驱动是通过中断。
评价IO虚拟化技术的两个指标——性能和通用性。性能,当然是越接近无虚拟化环境下的IO性能最好;而通用性,则是IO虚拟化对客户操作系统越透明越好。要想要高性能,最直接的方法就是让客户机直接使用真实的硬件设备;要想要通用性,则是要用想办法让客户机操作系统自带的驱动程序能够发现设备并操作设备。
客户机直接操作设备面临两个问题:第一,如何让客户机直接访问到设备真实的IO地址空间(包括IO和MMIO);第二,如何让设备的DMA直接访问客户机的内存空间。内存硬件虚拟化的EPT技术可以解决第一个问题。而VT-d技术则用来解决第二个问题。VT-d技术主要是引入地址重映射(IOMMU+IOTLB),负责提供重映射和设备直接分配。从设备端的DMA访问,都会进入地址重映射进行地址转换,使得设备可以访问到对应客户机特定的内存区域。
VT-d技术虽然可以将物理的IO设备直接透传给虚拟机,但是一台计算机系统受限于接口,可以连的物理设备毕竟有限。因此,PCIe SR-IOV技术应运而生。通过PCIe SR-IOV技术,一个物理IO设备可以虚拟出多个虚拟设备,分配给虚拟机使用。
如图 3.30(c)所示,SR-IOV引入了两个PCIe的功能类型:
Hypervisor把VF分配给虚拟机,通过IOMMU等硬件辅助技术提供的DMA数据映射,直接在虚拟机和硬件设备之间传输数据。
通过兼容性、性能、成本、扩展性四个方面对IO虚拟化技术进行总结,详见表 3.5:
表 3.5 不同IO虚拟化方式对比
IO虚拟化方式 |
VM的兼容性 |
性能 |
成本 |
扩展性 |
设备接口软件模拟 |
重用已有驱动 |
频繁的上下文切换 |
没有额外硬件成本 |
受设备模拟的性能代价约束 |
类虚拟化前后端 |
需要加载特定驱动 |
基于共享队列的机制减少了前后端交互 |
没有额外硬件成本 |
受设备后端的性能代价约束 |
直接分配VT-d |
重用设备驱动 |
直接访问物理设备,减少虚拟化开销 |
需要购买额外的较多的硬件 |
硬件设备独占性,受主板扩展槽限制 |
直接分配SR-IOV |
需要加载VF驱动 |
直接访问物理设备,减少虚拟化开销 |
需要购买额外的较少的硬件 |
硬件设备支持多个虚拟设备,扩展性较好 |
云计算的软件和硬件如何融合更高效?
未来的数据中心如何搭建?一起来学习《软硬件融合》吧。