之前的多篇文章介绍了网络虚拟化常见的技术实现,特别是virtio/vhost技术的实现。虽然virtio/vhost架构显著改善了虚拟网络的性能,但virtio网卡仍然是软件模拟的设备,其性能稳定性和资源占用率显然无法达到物理网卡的水平。虚拟网络其实还有一种实现方式——设备直通,让虚拟机与网卡直接交互,从而获得最高的网络性能。但这种方式显然无法大规模使用,因为物理网卡的数量是有限的,成本也很高,无法为每个虚拟机分配一个。
SR-IOV(Single Root I/O Virtualization)技术就是为了解决上述问题而产生的。通过SR-IOV技术,单个物理网卡能够提供多个网卡的接口和功能,从而让每个虚拟机都能直接和物理网卡通信,获得接近物理网卡的网络性能。
本文将讨论SR-IOV的基本原理和使用场景。
问题
- SR-IOV和MR-IOV有什么关系和区别?
- SR-IOV模拟出的VF和普通网卡在功能上和使用上有什么区别?
- 虚拟机是如何完成VF的配置和初始化的?
- 虚拟机与VF直接交互时,是如何注册设备的DMA地址的?
SR-IOV概念
SR-IOV中的SR(Single Root)是与MR-IOV相对的。SR-IOV和MR-IOV都是PCI-SIG定义的IO设备硬件虚拟规范。这里的Single Root和Multi Root中的Root指的是PCI根节点,基本上可以看做是单个计算节点的接入点。支持SR-IOV的IO设备只能同时为单个节点服务,相应的MR-IOV设备就能同时接入多个节点工作。MR-IOV主要是为刀片架构设计的,允许多个计算刀片通过同一个MR-IOV设备实现IO功能。普通服务器上的网卡只需要支持SR-IOV即可,例如Intel经典的82599系列。
SR-IOV是让PCIE设备扩展支持硬件虚拟化的规范,具体规范可见
https://composter.com.ua/documents/sr-iov1_1_20Jan10_cb.pdf
在规范中,定义了SR-IOV设备可以支持两个类别的功能:PF(Physical Function)和VF(Virtual Function)。
PF顾名思义就是普通物理设备原有的功能。只是在支持SR-IOV的设备上,PF还拥有了配置和初始化VF的能力。SR-IOV规范中要求PF增加了一个SR-IOV专用的寄存器,用于配置和开关SR-IOV能力。
VF就是虚拟化出来的虚拟设备。在操作系统角度看,VF是PCIE总线上的一个物理设备,只是和物理网卡共用一个PCIE slot。VF创建后,系统可以像操作普通网卡那样操作VF网卡,只是需要使用专门的网卡驱动。以intel的10GE网卡82599为例,PF的驱动是标准的ixgbe,VF的驱动是ixgbevf。
根据规范,单个PF可以生成65536个VF,但实际上网卡不可能支持这么多VF。网卡支持的具体VF数量与网卡的硬件资源有关,例如82599支持64个VF。
SR-IOV的使用
SR-IOV虽然是为虚拟化环境设计的,但从功能和使用上说和软件层面的虚拟化没有什么直接关系。对VF的创建和配置是在PF驱动的基础上执行的,通过PF驱动向上暴露的接口操作。例如通过/sys/bus/pci/devices/$BDF/sriov_numvfs就能动态创建指定数量的VF,在驱动加载时直接传入参数也能达到相同的效果。
在VF被创建后,在host系统中就可以当做是一个真实的物理网卡使用,可以通过内核驱动或DPDK的用户态驱动来操作。
如果要在guest中使用VF,需要在qemu启动虚拟机时配置设备直通模式,通过qemu实现guest对VF的配置和内存映射,最终让guest能够与VF直接DMA通信。大体结构如下图所示。
这里就有一些问题,guest是不能直接访问物理机的PCI总线和设备的,那么它是怎么发现和配置VF的?另外guest中使用的地址空间是GVA/GPA,VF如何使用这些地址去执行DMA?这些工作都需要在qemu和KVM的支持下完成。
QEMU设备直通
这里涉及到的技术称为QEMU设备直通。通过设备直通,guest中设备驱动对device的操作可以原样作用在host的物理设备上。设备直通的具体原理和实现可以参考
https://www.donglizhang.org/virt-passthrough.pdf
和
qemu VM device passthrough using VFIO, the code analysis
。大体上说,可以分为几个步骤:
- 在guest的虚拟PCI总线上模拟直通设备的存在,使guest OS可以检测到直通设备
- 将部分PCI bar设备地址空间(例如rx/tx ring、doorbell)映射到guest地址空间,使guest可以直接读写直通设备内存地址
- 通过IOMMU/VFIO映射GPA=>HPA地址,使guest写入设备内存的GPA地址可以被设备直接DMA访问
- 通过IOMMU/VFIO重定向设备中断
关于IOMMU和VFIO的部分可以参考上一篇文章
:网络虚拟化——virtio-user_dillanzhou的博客-CSDN博客
可以看到,设备直通在设备检测和初始化的阶段是需要qemu/kvm的支持的,但在初始化完成后数据面的交互是可以由guest与设备直接完成的。除了中断处理需要vfio/kvm参与外,guest与直通设备的通信过程和效率可以与host基本相同。
需要注意的是设备直通技术其实与SR-IOV也没有直接关系,只是在有了SR-IOV设备后设备直通技术才有了较大的应用空间。
小结
我们在本文中讨论了SR-IOV的概念以及在Host/Guest中的使用方法和实现。最后来看一下文章开始时的问题:
1. SR-IOV和MR-IOV有什么关系和区别?
SR-IOV只需要支持一个节点(其实就是PCI总线根节点,PCI Root Complex)。MR-IOV支持同时服务多个节点。MR-IOV是在SR-IOV的基础上增加了多节点支持,支持MR-IOV就必然支持SR-IOV。
2. SR-IOV模拟出的VF和普通网卡在功能上和使用上有什么区别?
从使用和表现上和普通网卡没有区别,但VF的功能特性和资源使用量可能比这个设备的PF要少,例如支持的队列数可能会较少,或者某些特性不支持。另外VF和PF最终需要共享带宽和资源。
3. 虚拟机是如何完成VF的配置和初始化的?
部分PCI bar空间(例如rx/tx ring)会被qemu映射到guest地址空间,让guest可以直接访问;另外部分较复杂的配置空间(例如MSI-X中断表),由qemu trap处理。
4. 虚拟机与VF直接交互时,是如何注册设备的DMA地址的?
qemu会维护GPA=>HPA的页表信息,guest只需要向设备写入GPA地址,设备DMA访问时IOMMU会根据页表查询到HPA地址并访问。
通过SR-IOV技术,虚拟机和容器可以直接向网卡收发报文,网络性能不再受限于vhost的处理和转发性能,也节省了vhost的资源开销。
但在虚拟机中使用网卡VF也产生了一个问题,就是虚拟机必须使用VF对应的驱动,这就导致虚拟机在不同物理机间的迁移受到了限制。如果两台物理机使用了不同厂商型号的网卡,由于VF驱动不同,热迁移是不可能实现的,冷迁移也要求guest系统有很好的设备自适应和配置能力。此外,如果网卡的固件和功能升级,guest中的VF驱动版本可能也需要升级,这对虚拟机的部署运维来说也是个很麻烦的问题。
在下一篇文章中,我们将讨论vDPA技术,这种技术让SR-IOV网卡的VF提供标准的virtqueue数据面接口,同时保留在驱动中自定义控制面功能的灵活性。从而解决虚拟机对特定网卡和驱动的依赖,同时保留网卡功能的多样性和可扩展性。