当前位置: 首页 > 科技观察

浅谈Linux设备虚拟化技术的演进

时间:2023-03-22 10:10:23 科技观察

前言设备虚拟化技术一直是云计算领域最重要的基础技术之一。我们在虚拟机中看到的各种设备,如网卡、磁盘、键盘、鼠标等,都离不开这项技术的帮助。在这篇文章中,我们将从技术演进的角度来谈谈Linux现有的和即将出现的设备虚拟化技术。陷阱和仿真在其早期阶段,设备虚拟化通常与QEMU等机器仿真器技术捆绑在一起。我们可以通过QEMU模拟真实设备的所有寄存器布局和操作过程。当QEMU虚拟机中的设备驱动需要访问虚拟设备的寄存器时,这条访问指令会被困到QEMU中,由QEMU处理。这样,虚拟机中的设备驱动程序就如同访问真实的硬件设备一样操作虚拟设备,设备驱动程序不需要做任何改动。Virtio通过上面提到的trap-and-emulate方法来模拟设备。虽然不需要改变真实的设备驱动,但是在设备访问过程中频繁的trapping&trapping会导致严重的性能问题。于是,virtio这种准半虚拟化技术应运而生,并在2008年被纳入Linux内核的主线。与trap-and-emulate的方式相比,Virtio不再拘泥于已有的设备驱动,而是定义了一套新的驱动专用于虚拟设备的框架。设备驱动知道自己操作的是一个虚拟设备,因此避免了在真实I/O路径上可能造成trapping&trapping的大量mmio/pio操作,从而提高了性能。虚拟机中的Virtio驱动与QEMU模拟的Virtio设备之间的数据交互,本质上是一种基于共享内存+环形队列的通信机制。核心数据结构(splitvirtqueue)包括:两个ringbuffer(availring,usedring)和一个描述符表。工作机制类似于DMA。虚拟机中的virtio驱动首先将内存中需要传输的一个hashbuffer的地址和长度组成的描述符写入描述符表中,然后将这些描述符写入对应的描述符表中。index写入availring,通过eventfd机制通知宿主机上的virtiobackend。由于这些ringbuffer、descriptortable、hashbuffer都在共享内存中(虚拟机本质上是一个用户态进程,虚拟机的内存由用户态申请和分配,可以与其他进程共享,如:SPDK、DPDK等),因此,VirtioBackend可以直接访问并获取hashbuffer的地址和长度,然后直接访问这些hashbuffer。VirtioBackend处理完请求后,将数据填充到相应的buffer中,将相应的描述符表索引写入usedring,并通过eventfd机制注入中断通知虚拟机中的virtiodriver。引入VhostVirtio技术后,Virtio设备通常被模拟在QEMU中,数据收发需要经过QEMU,然后进入虚拟机。但渐渐地,开发者发现在模拟网卡时,QEMU中的数据收发最终还是需要困在内核中,通过系统调用来操作网卡硬件进行实际的数据收发。那么,有什么办法可以优化从QEMU到内核的上下文切换及其带来的额外拷贝开销呢?Linux内核社区终于在2010年整合了vhost技术进行优化,将virtio的数据平面卸载到内核线程中进行处理,从而使virtio通信机制从原来的QEMU用户态I/O线程和虚拟机驱动(QEMU用户态vcpu线程)与vhost内核I/O线程和虚拟机驱动(QEMU用户态vcpu线程)线程)通信。vhost内核I/O线程拿到数据包后,直接进入内核协议栈和网卡驱动进行处理,从而优化了QEMU对内核态的额外开销。VFIO随着云计算规模不断扩大,用户不再满足于Virtio等半虚拟化设备带来的性能体验,另一方面GPU等难以实现vi??rtio的设备应用场景日渐增多按天。在此背景下,VFIO技术被提出并于2012年纳入Linux内核主线。VFIO的全称是VirtualFunctionI/O。它实际上是一个用户态设备驱动框架。与早期的uio用户态设备驱动框架相比,VFIO可以有效利用硬件IOMMU机制进行安全隔离,因此可以广泛应用于云计算等多租户需求的场景中。如上图所示,通过VFIO,QEMU可以直接打通虚拟化PCI设备与物理PCI设备之间的数据链路。当虚拟机中的设备驱动访问虚拟PCI设备的barspace时,EPT机制,此时mmio访问会重定向到真实物理设备对应的barspace位置,不需要trap到QEMU。这样,虚拟机驱动就相当于直接访问真实的物理设备,接近于零消耗,性能可以达到最佳。同时VFIO驱动使用IOMMU实现设备DMA和中断的重映射。一方面起到隔离作用,即一个虚拟机不能操作VFIOpass-through设备向同一主机上的其他虚拟机发起DMA和中断。它保证了设备在执行DMA时可以通过给定的虚拟机物理地址直接访问正确的物理内存。Vhost-user,VFIO虽然可以给虚拟机带来接近物理机的I/O性能体验,但是这个技术还是有一个缺陷,就是不支持livemigration,虚拟机有一个VFIO设备将无法像传统的virtio设备那样运行。像虚拟机一样执行实时迁移。这使得开发者开始探索新的设备虚拟化技术,既能满足性能需求又能灵活运维。2014年融入QEMU社区的vhost-user技术就是其中之一。因为QEMU和vhost的线程模型对I/O性能的优化并不友好,每个虚拟机都是分离线程来处理I/O的。从整个系统的角度来看,这种方法可能不是最优的。因此,vhost-user提出了一种新的方法,就是将virtio设备的数据平面卸载到另外一个专用进程进行处理。这样,由于是专用进程,线程模型不再受传统QEMU和vhost线程模型的限制,可以任意优化。同时,它还能够以1:M的方式同时处理多个虚拟机的I/O请求,并且相比于vhost内核线程的方式,用户进程在操作和处理上更加灵活维护。vhost-user框架自提出以来就受到了广泛的关注,目前已经扩展到基于轮询+用户态驱动的SPDK和OVS-DPDK。核心新的虚拟机I/O服务模型。在VFIO-mdevVFIO技术的实际应用场景中,除了上面提到的不支持热迁移的问题外,还有一个限制就是一个设备只能透传给一个虚拟机,无法实现资源共享。SR-IOV技术在一定程度上可以解决这个问题,即将一个物理PCI设备从硬件层面划分成多个VF,透传给多个虚拟机使用,但是很多设备可能不具备SR-IOV能力,因此,Linux内核社区在2016年纳入了VFIO-mdev技术框架,希望提供一个标准的接口,帮助设备驱动程序在软件层面实现资源分割,并使用VFIO技术透传给虚拟机。该技术本质上是在内核中实现了一个虚拟设备(Mediateddevice)总线驱动模型,并在VFIO内核框架上进行了扩展,增加了对mdev(mdevbusdriver)等虚拟设备的支持,从原来只支持从中获取透传信息标准硬件PCI设备和硬件平台设备,如:PCI条空间,变成既直接从硬件设备获取,又从mdev设备驱动程序定义的虚拟设备接口获取。这样,例如当需要将一个PCI设备的条空间划分为一个资源时,通过实现一个合适的mdev设备驱动,就可以将条空间透传到不同的虚拟机,粒度为4KB(page尺寸)。vDPAVFIO和virtio这两项技术一直是最主流的设备虚拟化技术。VFIO可以直接将硬件资源传输给虚拟机使用,性能最好。virtio的性能略逊一筹,但更灵活。是否可以结合两者的优点?2020年将纳入Linux内核主线的vDPA技术框架就是为了实现这个目标。vDPA全称VirtioDataPathAcceleration,代表一类设备:这类设备的数据平面处理严格遵循Virtio协议规范,即驱动和设备会按照Virtio通信流程进行通信Section3中提到过,但是Controlpaths,比如:通信过程中提到的ringbuffer的内存地址和描述符表,driver如何通知设备,设备支持的特性,driver如何感知这些都是由厂商定制,不一定遵循Virtio协议。这样做的好处是可以降低制造商实施此类设备的复杂性。为了应用这样的设备,Linux内核提出了vDPA这样的技术框架。这个技术框架在本质上类似于VFIO-mdev,同样实现了一个虚拟设备(vDPAdevice)总线驱动模型。与VFIO-mdev不同的是,通过vDPA框架虚拟化的设备可以被虚拟机使用,也可以直接从宿主机(如:容器)访问。这一切都是因为vDPA设备的数据路径遵循Virtio协议规范,所以可以直接被宿主机上的virtio驱动访问。同时,该技术框架扩展了vhost内核子系统,赋予其类似VFIO技术框架的功能,允许硬件资源(环形缓冲区、描述符表、门铃寄存器等)这样,当virtio虚拟机的驱动进行数据通信,也是直接访问硬件资源,不需要通过vhost,vhost-user等处理。更重要的是,由于虚拟机驱动是原始的virtio驱动,当需要的时候为支持热迁移,QEMU可以灵活切换到软件模拟,保证热迁移的顺利进行。这样,vDPA这种设备虚拟化技术框架,既保证了最佳性能又保留了virtio设备的灵活性,同时也统一了虚拟机和容器的I/O技术栈。通过上述vDPA技术框架,VDUSE基本解决了长期以来设备虚拟化技术在虚拟机场景下暴露出的一些问题,更重要的是,还将virtio技术带到了容器领域。但是这个技术框架还有一个问题,就是需要硬件设备的支持。回想一下前面提到的virtio、vhost和vhost-user本质上是软件定义的虚拟设备。有没有可能vDPA的技术框架也可以使用软件定义设备?VDUSE就是用来实现这个目标的技术。通过VDUSE,我们可以在一个用户进程中实现一个软件定义的vDPA设备,并通过上面的vDPA框架连接到virtio或vhost子系统,供容器或虚拟机使用。该技术由我们自主研发,并于去年10月正式开源给Linux内核社区。现阶段,我们的解决方案已经纳入Linux内核主线,将在Linux5.15中可用。同时,我们还将在9月15日举办的虚拟化领域高端技术论坛KVM论坛上进行在线分享。结语从服务虚拟机到支持容器,从纯软件模拟到硬件透传再到软硬件一体化,几十年来Linux设备虚拟化技术一直在朝着极致性能和应用灵活性的方向演进。随着云原生的浪潮,各大硬件厂商的入局,软硬件结合的新方式层出不穷,相信未来会有更多精彩的技术等着我们。