在上一篇文章《网络虚拟化——SR-IOV_dillanzhou的博客-CSDN博客》中,我们介绍了SR-IOV技术。SR-IOV网卡可以在网卡硬件上虚拟出功能与普通网卡相同的VF设备,通过qemu的vfio设备直通技术,可以让guest直接与物理网卡直接交互完成报文收发。由于减少了虚拟网卡的后端实现与host协议栈转发流程,采用VF直通后guest的网络性能可以与host基本相同,且没有额外性能开销。
但使用VF直通后,虚拟机OS就需要感知物理机网卡的类型,并加载特定的网卡VF驱动。这使得虚拟机与特定的硬件设备和软件驱动绑定了。这就导致虚拟机在不同物理机间的迁移受到了限制。如果两台物理机使用了不同厂商型号的网卡,由于VF驱动不同,热迁移是不可能实现的,冷迁移也要求guest系统有很好的设备自适应和配置能力。此外,如果网卡的固件和功能升级,guest中的VF驱动版本可能也需要升级,这对虚拟机的部署运维来说也是个很麻烦的问题。
为了解决VF通用性问题,直接的思路就是将VF的数据面和控制面接口统一起来,这样guest只需要使用一个通用的驱动就能操作不同网卡的VF。而virtio作为虚拟网络的事实标准,自然也就成为了这个通用接口的首选。将网卡VF的控制面配置接口和数据面传输接口完全按virtio标准实现,就是这种思路的具体实现。阿里云的神龙网卡就采用了这种方式来提供通用网卡接口。通过这种方式,不管虚拟机是否使用了VF直通网卡,都可以通过标准的virtio-net驱动实现网络IO,也就支持了虚拟机在神龙服务器和普通服务器上的迁移。
在virtio硬件实现的基础上,又出现了一种技术,称作vDPA(virtio data path acceleration)。顾名思义就是只用硬件加速virtio的数据面。在vDPA技术框架中,硬件设备只需要支持virtio的数据面接口,也就是virtqueue/vring队列结构,控制面接口和实现仍然可以保留设备特有的方式。vDPA的意义在于降低了网卡支持virtio接口的难度。对于网卡厂商来说,网卡的数据队列布局改用vring的实现难度不算太大,但将控制面的逻辑全部适配到virtio的接口和实现的工作量就非常大。通过vDPA框架,网卡厂商通过两种不同的方式让网卡提供virtio数据面(硬件支持)和控制面接口(软件驱动转换),既实现了高性能的数据面收发,又避免了对网卡控制面逻辑的大量改造和开发工作。
本文将讨论vDPA技术的原理和实现。
本文内容和图片很多来自于RedHat的系列vDPA介绍文章,可以阅读这些文章来获得更详细的信息:
Introduction to vDPA kernel framework
vDPA kernel framework part 1: vDPA bus for abstracting hardware
vDPA kernel framework part 2: vDPA bus drivers for kernel subsystem interactions
vDPA kernel framework part 3: usage for VMs and containers
问题
1. vDPA是用户态框架还是内核态框架?如果都有,用户态的vDPA和内核态的vDPA框架有什么异同?
2. 使用vDPA设备时,guest、host、user space、kernel space下使用的驱动还是标准的virtio-net和virtio-pmd吗?是否需要什么改造?
3. 有哪些网卡真正支持了vDPA?
4. 除了便于网卡实现之外,vDPA是否还有其他方面的用途?
vDPA
vDPA最早出现在DPDK框架中,是vhost Data Path Acceleration的缩写,提供了对vDPA设备的virtio接口支持。之后内核社区才开始了内核vDPA框架的设计和开发,到2020年3月vDPA正式合入linux内核主线。内核中的vDPA是virtio Data Path Acceleration的缩写,与DPDK有着微妙的差别。
vhost Data Path Acceleration in DPDK
在DPDK中,vDPA的‘v’代表vhost,原因是DPDK中vDPA是作为vhost-user的一种硬件加速实现而存在的。qemu或virtio-user进程与vhost-user的交互接口不变,并不感知vhost-user后端是纯软件实现的还是vDPA硬件实现的,由vhost-user应用决定virtio设备最终的数据面实现。
从上图中可以看到,通过vhost-user和vdpa,qemu和virtio-user事实上是直接与vdpa硬件设备交互收发数据的,性能上与设备直通模式基本相同,但对qemu和virtio-user屏蔽了底层实现的具体方式,只暴露了一个标准的virtio-net设备接口。对vhost-user来说,vdpa模式与通过pmd driver向网卡转发是不同的,vdpa模式下,vhost-user只负责网卡的vdpa模式配置和初始化,后续的数据收发不需要vhost-user参与;而通过pmd driver转发是需要vhost-user处理virtqueue和网卡队列信息并在这两种队列间转发数据的。
从DPDK的实现来看,vdpa是设备驱动的一种模式,实现vhost-user的进程会通过设备的这套驱动实现网卡硬件的初始化和virtqueue信息同步。
理论上说,qemu和virtio-user也可以直接通过设备的vdpa驱动来使用设备,但这就将设备实现和复杂性暴露到了更上层的实现中,vDPA的意义就变小了。
virtio Data Path Acceleration in Linux kernel
在网卡设备支持了vDPA并在DPDK中得到了应用之后,Linux内核社区也开始了对vDPA的支持工作。内核的vDPA框架设计经过了多个版本的变化,最终合入的版本与初期设计的方案有很大的差异,本文只讨论最终合入主线的vDPA框架实现。
上图是内核vDPA框架的大体架构。可以看到内核的vDPA框架可以通过两种方式使用。
一种方式和DPDK中类似,通过内核的vhost-net模块配置和使用vDPA设备。这种方式扩展了内核原有的vhost子系统,vhost通过用户态配置接口获取virtqueue和控制面信息后,调用vDPA框架的接口完成对vDPA设备的配置。qemu和host上使用virtio-user的应用可以通过这种方式使用vDPA设备。上图右侧部分就表示了这种方式。
另一种方式则通过扩展内核中的virtio驱动来使用vDPA设备。在这种方式下,vDPA设备最终通过virtio驱动向上呈现为一个标准的virtio设备。对这个virtio设备的配置操作会被virtio驱动处理,virtio驱动再将这些操作转交给vDPA框架,最终通过vDPA设备专用的vDPA驱动完成配置。通过这个方式,普通的host应用也可以使用vDPA设备。这个方式的主要应用场景是容器网络,通过这种方式,可以为运行在host上的每个容器netns提供独立的硬件网卡,大幅降低容器网络的复杂度、提升性能。上图左侧部分就表示了这种方式。
由于内核的vDPA框架不一定通过vhost方式使用,因此名字也就改成了更宽泛的virtio Data Path Acceleration。
小结
本文介绍了vDPA技术的意义、原理,以及在DPDK和内核中的大体实现框架。最后看一下相关问题:
1. vDPA是用户态框架还是内核态框架?如果都有,用户态的vDPA和内核态的vDPA框架有什么异同?
vDPA有DPDK中的用户态框架和Linux内核中的内核态框架。DPDK中的框架主要通过DPDK的vhost-user调用,而内核中的框架可以通过内核的vhost模块或virtio驱动来调用。两者的区别也反映在了DPDK和内核vDPA框架全称的差别上。
2. 使用vDPA设备时,guest、host、user space、kernel space下使用的驱动还是标准的virtio-net和virtio-pmd吗?是否需要什么改造?
使用virtio驱动有4种情况组合,需要分别讨论:
- guest kernel driver:这种情况下guest中使用标准的virtio-net驱动,qemu也使用标准的vhost接口与vhost-net/vhost-user交互,只是vhost后端通过内核/DPDK的vDPA框架最终由vDPA设备实现。
- guest userspace driver:这种情况下guest使用标准的virtio-pmd。在虚拟机中不管用户态还是内核态,看到的都是qemu模拟的标准PCI virtio设备,不感知vDPA设备的存在。
- host kernel driver:这种情况下host上的应用通过posix socket接口实现网络通信,不用关心内核驱动的具体实现。内核中virtio驱动通过vDPA框架和vDPA驱动来完成设备控制面配置,数据面的收发仍然在virtio驱动中实现。
- host userspace driver:这种情况下不能使用标准的virtio-pmd,因为virtio-pmd会尝试通过virtio控制面标准接口来配置设备。这时需要使用virtio-user,通过vhost-net/vhost-user来使用内核/DPDK的vDPA框架。
3. 有哪些网卡真正支持了vDPA?
目前支持vDPA的网卡有Intel FPGA 100G VF、Mellanox ConnectX-6, Mellanox ConnectX-6 Dx、Mellanox BlueField和Xilinx SN1022 SmartNIC。
4. 除了便于网卡实现之外,vDPA是否还有其他方面的优点?
vDPA的另一个优点是又提供了一个中间层,能够实现virtio不同后端实现的透明切换。与直接通过virtio驱动操作virtio offloading的硬件设备相比,vDPA在virtio驱动和vDPA硬件之间又实现了一层。这使得如果vDPA硬件设备出现不可用的情况时,virtio的实现可以立即切换为纯软件的实现,通过软件实现virtqueue的收发操作。
基于这种场景,内核又引入了vduse框架,来支持在用户态软件实现vDPA设备。在下一篇文章中我们将继续讨论这项技术。