0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

VirtIO Networking虚拟网络设备实现架构

SDNLAB 来源:SDNLAB 2023-05-08 10:48 次阅读

VirtIO

VirtIO 由 Rusty Russell 开发,最初是为了支持自己开发的 lguest Hypervisor,其设计目标是在虚拟化环境下提供与物理设备相近的 I/O 功能和性能,并且避免在虚拟机中安装额外的驱动程序。基于这一目标,后来通过开源的方式将 VirtIO 延伸为一种虚拟化设备接口标准,并广泛地支持 KVM、QEMU、Xen 和 VMware 等虚拟化解决方案。

为了追求更高的性能和更低的开销表现,VirtIO 采用了 Para-virtualizaiton(半虚拟化/准虚拟化)技术路线,本质区别于性能低下的 Full-virtualizaiton(e.g. QEMU I/O Emulation)。这也意味着使用 VirtIO 的 GuestOS 需要经过一定的代码修改(安装非原生的 Device Driver),这也是为什么需要将 VirtIO 定位于 “虚拟化设备接口标准“ 的原因,其整体的集成架构需要由 Front-end(GuestOS Kernel Device Driver)和 Back-end(VMM Provider)共同遵守统一的传输协议。

6ececcc6-ec67-11ed-90ce-dac502259ad0.png

在应用 VirtIO 的场景中,除了 GuestOS 需要安装额外的 VirtIO Front-end Device Driver 这一点不足之外(通常在制作 QCOW2 镜像时会安装好),相对地带来了下列诸多好处:

高性能:VirtIO 省去了 Full-virtualizaiton 模式下的 Traps(操作捕获)环节,GuestOS 通过 VirtIO Interfaces 可以直接与 Hypervisor 中的 Device Emulation 进行交互。

低开销:VirtIO 优化了 CPU 在内核态和用户态之间频繁切换,以及 CPU 在 VM Exit 和 VM Entry 之间频繁陷入陷出所带来的性能开销。

标准化:VirtIO 实现了统一的虚拟设备接口标准,可以应用在多种虚拟化解决方案中。

6ee1eaf4-ec67-11ed-90ce-dac502259ad0.png

VirtIO 虚拟设备接口标准

为了抑制 Para-virtualizaiton 所具有的跨平台兼容性缺点,VirtIO 明智地走上了开源之路,通过构建标准而统一的生态来争取最小化的兼容性排斥问题,反而让其逆转成为了一种优势。

在 VirtIO 提出的虚拟化设备接口标准中,包括多个子系统,每个子系统都定义了一组虚拟设备类型和协议。例如:

VirtIO-Block(块设备):提供虚拟磁盘设备的接口。

VirtIO-Net(网络设备):提供虚拟网络设备的接口。

VirtIO-Serial(串口设备):提供虚拟串口设备的接口。

VirtIO-Memory(内存设备):提供虚拟内存设备的接口。

VirtIO-Input(输入设备):提供虚拟输入设备的接口。

此外还有 VirtIO-SCSI、VirtIO-NVMe、VirtIO-GPU、VirtIO-FS、VirtIO-VSock 等等虚拟设备类型和协议。

VirtIO 的前后端分层架构

VirtIO 虚拟设备接口标准的分层软件架构如下图所示:

Front-end:是一组通用的,安装在 GuestOS Kernel 中的 VirtIO Device Driver,通过 Hyper-call 的方式对 Back-end 进行调用。

Back-end:是一组 Hypervisor 专用的,运行在 VMM 中的设备模拟程序,提供了 Hyper-call 调用接口。

Transport:是一组标准的传输层接口,基于环形队列的方式来批量处理 I/O 请求。

6f04d564-ec67-11ed-90ce-dac502259ad0.png

VirtIO 的数控路径分离架构

VirtIO 还定义了 “控制路径” 和 “数据路径” 的分离架构,两者的侧重各有不同,控制平面追求尽可能的灵活以兼容不用的设备和厂商,而数据平面则追求更高的转发效率以快速的交换数据包。

控制路径:控制建立或删除 Front-end 和 Back-end 之间的数据路径,提供可管理的灵活性。

数据路径:在 Front-end 和 Back-end 之间进行数据传输,追求性能。

对应地,VirtIO 标准也可以分为两个部分:

VirtIO Spec:定义了如何在 Front-end 和 Back-end 之间构建控制路径和数据路径的标准,例如:数据路径规定采用环形队列缓冲区布局。

Vhost Protocol:定义了如何降数据路径的高性能实现标准,例如:基于 Kernel、DPDK、SmartNIC Offloading 的实现方式。

以 QEMU 为例,其根据 VirtIO Spec 实现了控制路径,而数据路径则可以 Bypass QEMU,使用 vhost-net、vhost-user 等实现。

VirtIO Networking

VirtIO Networking 是一种高功能、高性能、可扩展的虚拟化网络设备,支持多种网络功能和虚拟网络技术,并可以通过多种实现方式进行部署。

网络功能:MAC 地址、流量限制、流量过滤、多队列收发等;

虚拟网络技术:VLAN、GRE、VXLAN 等;

多种实现方式:Kernel、DPDK、硬件网卡等。

virtio-net Driver 和 virtio-net Device(由 QEMU 模拟的后端)

virtio-net 是 VirtIO Networking 的默认实现。其中,Front-end 是 virtio-net Driver(虚拟网卡驱动程序);Back-end 是由 QEMU 软件模拟的 virtio-net Device。

QEMU 会在 VM 启动时,为 VM 创建好相应的 virtio-net Device(虚拟设备),并在 VM 启动后,通过在 GuestOS Kernel 中安装的 virtio-net Driver 来 Probe(探知)到该 virtio-net Device。

6f81faa8-ec67-11ed-90ce-dac502259ad0.png

virtio-net Driver 和 virtio-net Device 的软件架构如下图所示,我们需要关注 3 个方面:

Control Plane:virtio-net Driver 和 virtio-net Device 之间使用了 PCI 传输协议,如下图中蓝线部分。

Data Plane:virtio-net Driver 和 virtio-net Device 之间使用了 Virtqueues 和 Vrings,如下图中红虚线部分。而 virtio-net Device 和 Kernel Network Stack 之间使用了 Tap 虚拟网卡设备,作为 User space(QEMU)和 Kernel space(Network Stack)之间的数据传输通道,如下图中红实线部分。

Notification:作为 virtio-net Driver、virtio-net Device 和 KVM 之间交互方式,用于实现 “vCPU 硬中断“ 的功能。

6fa6be74-ec67-11ed-90ce-dac502259ad0.png

其中值得细究的就是 virtio-net Driver 和 virtio-net Device 之间的 Transport(传输层)实现。virtio-net Transport 采用了非常类似于物理网卡设备(NIC Rx/Tx Queues 和 Kernel Rx/Tx Rings)的设计思路。

Front-end 和 Back-end 之间存在 2 个 Virtqueues,对应到 NIC 的 Rx/Tx Queues。Virtqueues 的底层利用了 IPC 共享内存技术,在 HostOS 和 GuestOS 之间建立直接的传输通道,绕开了 VMM 的低效处理。

Receive Queue:是一块 Buffer 内存空间,存放具体的由 Back-end 发送到 Front-end 数据。

Send Queue:是一块 Buffer 内存空间,存放具体的由 Front-end 发送到 Back-end 数据。

同时,每个 Virtqueue 都具有 2 个 Vrings,对应到 Kernel 的 Rx/Tx Rings:

Available Ring:存放 Front-end 向 Back-end 发送的 Queue 中可用的 Buffer 内存地址。

Used Ring:存放 Back-end 向 Front-end 发送的 Queue 中已使用的 Buffer 内存地址。

当然,Front-end 和 Back-end 之间还需要一种双向通知机制,对应到 NIC 和 CPU 之间的硬中断信号

Available Buffer Notification:Front-end 使用此信号通知 Back-end 存在待处理的缓冲区。

Used Buffer Notification:Back-end 使用此信号标志已完成处理某些缓冲区。

具体的,当 GuestOS 发送数据时,Front-end 将数据填充到 Send Queue 内存空间,然后将地址记录到 Available Ring,并在适当的时候向 Back-end 发送 Available Buffer Notification;QEMU 接收到通知后,从 Available Ring 中获取到数据的数据,完成数据接收,然后记录 New Buffer Head Index 到 Used Ring,并在适当的时候向 Front-end 发送一个 Used Buffer Notification。Front-end 接收到通知后释放对应的 Send Queue 内存空间,Available Ring 指针指向下一位。

当 GuestOS 接收数据时,Front-end 首先分配好 NULL 的 Receive Queue 内存空间,然后将地址记录到 Available Ring,并在适当的时候向 Back-end 发送 Available Buffer Notification;QEMU 接收到通知后,从 Available Ring 中获取到数据填充入口地址,完成数据填充,然后记录 New Buffer Head Index 到 Used Ring,并在适当的时候向 Front-end 发送一个 Used Buffer Notification。Front-end 接收到通知后从 Receive Queue 中读取数据,Available Ring 指针指向下一位。

值得注意的是,在 PCI Passthrough 场景中,可以使用 virtio-pci(更多的是使用 VFIO)。虽然此时依旧会沿用了 Available/Used buffer notification 这一控制面的双向通知机制,但实际的数据面,则是由 DMA 和专用队列来完成的,具有更高的性能。这体现了数控分离带来的好处。

6fbaaede-ec67-11ed-90ce-dac502259ad0.png

综上所述,下述流程图总结了 2 个关键流程:

virtio-net Device 初始化流程:包括 Device discovery 和 Device configuration。对于 virtio-net Driver 而言,virtio-net Device 就是一个 PCI 设备,遵守标准的 PCI 设备初始化流程,并且 Driver 和 Device 使用 PCI 协议进行通信

virtio-net Driver 发包流程:

当 virtio-net Driver 发送数据包时,将数据包放入 Send Queue,将数据包的访问地址放入 Available Ring,触发一次 Available Buffer Notification 到 KVM,然后 VM Exit,由 QEMU 接管 CPU,执行 I/O 控制逻辑,将此数据包传递到 virtio-net Device,然后 virtio-net Device 降数据包通过 Tap 设备传入 Kernel Network Stack;

完成后,QEMU 将 New Buffer Head Index 放入到 Used Ring 中,同时 virtio-net Device 发出一个 vIRQ 中断注入到 KVM,然后 KVM 发出一个 Used Buffer Notification 到 virtio-net Driver,此时 virtio-net Driver 就会从 Used Ring 中取出 Buffer Head Index;

至此一次发送操作就完成了。

另外,由于 Tap 设备支持 Tx/Rx 多队列,所以实际上也会存在 N 个 Virtqueues Peer 进行一一映射。

6fda39e8-ec67-11ed-90ce-dac502259ad0.png

vhost-net(由 Kernel 提供的后端)

由 QEMU 模拟的 virtio-net Device 显然性能不佳,具有频繁的模式和上下文切换、低效的数据拷贝、线程间同步等性能问题。于是,VirtIO 社区在 Kernel 中实现了一个新的 vhost-net 后端,以解决上述问题。

更低的延迟(latency):比普通 virtio-net 低 10%。

更高的吞吐量(throughput):比普通 virtio-net 高 8 倍,达到 7~8 Gigabits/Sec。

vhost-net 的核心思想就是将 Data Path Bypass QEMU,定义了一种新的 Data Path 传输方式,使得 GuestOS virtio-net Driver 和 HostOS Kernel vhost-net 可以直接通信。如下图所示:

Control Plane:virtio-net Driver 和 virtio-net Device 之间使用了 PCI 传输协议,virtio-net Device 和 vhost-net 之间使用 ioctl() 接口,如下图中蓝线部分。

Data Plane:virtio-net Driver 和 vhost-net 直通,如下图中虚线部分。而 vhost-net 和 Kernel Network Stack 之间使用了 Tap 虚拟网卡设备连接,如下图中红实线部分。

Notification:作为 virtio-net Driver、vhost-net 和 KVM 之间交互方式,用于实现 “vCPU 硬中断“ 的功能。

70185a48-ec67-11ed-90ce-dac502259ad0.png

vhost-net 的本质是一个 HostOS Kernel Module,实现了 vhost-net Protocol 标准,当 Kernel 加载 vhost-net 后,会暴露一个设备接口文件 /dev/vhost-net。

当 QEMU 在 vhost-net 模式下启动时,QEMU(virtio-net Device)首先会 open() 该文件,并通过 ioctl() 与 vhost-net 进行交互,继而完成 vhost-net 实例的 Setup(初始化)。初始化的核心是建立 virtio-net Driver 和 vhost-net 之间的 Data Path 以及 Notification,包括:

Hypervisor Memory Layout(虚拟化内存布局):用于 Data Path 传输,让 vhost-net 可以在 KVM 的内存空间中找到特定 VM 的 Virtqueues 和 Vrings 的地址空间。

ioeventfd 和 irqfd(文件描述符):用于 Notification 传输,让 vhost-net 和 KVM 之间可以在 Kernel space 中完成 Notification 的直接交互,不再需要通过 User space 中的 QEMU。

同时,在 vhost-net 实例初始化的过程中,vhost-net 会创建一个 Kernel Thread(vhost worker thread),名为 vhost-$pid(pid 是 QEMU 进程 PID),QEMU 进程就和 vhost-net 实例以此建立了联系。vhost worker thread 用于处理 I/O Event(异步 I/O 模式),包括:

使用 ioeventfd 轮询 Tap 事件和 Notify 事件,并转发数据。

使用 irqfd 允许 vhost-net/KVM 通过对其进行写入来将 vCPU 的 vIRQ 注入到 virtio-net Driver。

综上,在 vhost-net 实例初始化完成之后,virtio-net Device 将不再负责数据包的处理(对 Virtqueues 和 Vrings 的读/写操作),取而代之的是 vhost-net。vhost-net 可以直接访问 VM 的 Virtqueues 和 Vrings 内存空间,也可以通过 KVM 与 virtio-net Driver 进行 Notification 交互。

704841e0-ec67-11ed-90ce-dac502259ad0.png

最后需要注意的是,vhost-net 在某些应用场景中的性能未必就会比 virtio-net Device 更好。例如:从 HostOS 传输到 GuestOS 的 UDP 流量,如果 GuestOS 接受 UDP 数据包的速度比 HostOS 发送的速度要慢,在这种情况下使用 vhost-net 将会导致 GuestOS UDP Socket Receive Buffer 更容易溢出,导致丢包,继而使得 GuestOS 的整体性能出现下降。此时使用慢速的 virtio-net,让 HostOS 和 GuestOS 之间的传输速度稍微慢一点,反而会提高整体的性能。

可见,在虚拟机场景中,全链路的性能均衡需要给予更加全面的考虑。

vhost-user(由 DPDK 实现的用户态后端)

vhost-user 是一个基于 DPDK vhost-user Library 开发的后端,运行在 User space,应用了 DPDK 所提供的 CPU 亲和性,大页内存,轮询模式驱动等数据面转发加速技术。

区别于 vhost-net Protocol,vhost-user Library 实现了一种新的 vhost-user Protocol,两者间最大的区别体现在通信信道的实现方式上。

vhost-net:使用 /dev/vhost-net 字符设备和 ioctl() 实现了 User Process(QEMU)和 Kernel(vhost-net)之间的 Control Plane 通信信道。

vhost-user:使用 Unix Socket 实现了 User Process(QEMU 和 DPDK App)之间的 Control Plane 通信信道。

QEMU 通过 Unix Socket 来完成对 vhost-user 的 Data Plane 配置,包括:

特性协商配置:QEMU(virtio-net Device)与 vhost-user 协商两者间功能特性的交集,确认哪些功能特性是有效的。

内存区域配置:vhost-user 使用 mmap() 来映射分配给 QEMU 的内存区域,建立两者间的直接数据传输通道。

Virtqueues/Vrings 配置:QEMU 将 Virtqueues/Vrings 的数量和访问地址发送给 vhost-user,以便 vhost-user 访问。

Notification 配置:vhost-user 仍然使用 ioeventfd 和 irqfd 来完成和 KVM 之间的通知交互。

7064fac4-ec67-11ed-90ce-dac502259ad0.png

目前最常见的 vhost-user DPDK App 就是 OVS-DPDK,除了支持 vhost-user Back-end 之外,还支持 virtio-pmd Front-end。在追求极致性能的 vhost-user / virtio-pmd 架构中,HostOS User space 和 GuestOS User space 都运行着 DPDK。

用户可以自由选择创建 vhost-user 类型的 vSwitch Port(对应一个 vhost-user 实例)。如下图所示。

70c7bad8-ec67-11ed-90ce-dac502259ad0.png

HW vDPA(使用硬件加速的后端)

目前性能最好的 Data Plane 无疑是 SR-IOV VF Passthrough,但原生的 SR-IOV 缺少控制面逻辑,在实际使用中多有不便。

HW vDPA(Hardware vhost Data Path Acceleration,硬件 vhost 数据面加速)就是一种使用 SR-IOV VF 来充当 Data Plane、使用 vDPA Framework 来充当控制面的软硬件融合加速技术,能够同时兼具软件的可管理性、灵活性以及硬件的高性能。同时也解决了 VF Passthrough 虚拟机不支持热迁移的难题。

NOTE:SW vDPA(e.g. vDPA on OVS-DPDK)不在本文讨论范围中。

71330036-ec67-11ed-90ce-dac502259ad0.png

下图中展示了 OVS-DPDK 和 HW vDPA 的性能对比。

718b057e-ec67-11ed-90ce-dac502259ad0.png

目前 vDPA Framework 的底层实现方式还尚未统一,从 QEMU 的角度来看,主要有 2 种方式:

适应性更好的 vhost-user + vDPA Driver:在 DPDK vhost-user Library 的基础之上,再实现一个 vDPA Driver 适配层。由 vDPA Driver 完成与 HW Device(e.g. SmartNIC、DPU)之间的交互。从下图中可以看到 QEMU 与 HW 的 Control Plane 通过 vDPA driver 进行传递,并配置好 HW 与 VM 之间的 Passthrough Data Plane。目前 Mellanox MLX5 和 Intel IFC 对应的 vDPA Driver 都已经合入到 DPDK 和 Kernel 社区。(注:IOMMU/VFIO 实现原理请浏览《虚拟化技术 — 硬件辅助的虚拟化技术》。)

71a70bca-ec67-11ed-90ce-dac502259ad0.png

架构更合理的 vhost-vdpa:实现一种新的 vhost-vdpa Protocol,QEMU 通过 ioctl() 调用 Kernel 中的 vDPA Module,再由 vDPA Module 通过 vDPA Driver 完成与 HW Device 之间的交互。

72050e46-ec67-11ed-90ce-dac502259ad0.png

目前,随着 SmartNIC / DPU 的快速发展,一种结合了 SW vDPA 和 HW vDPA 特性的 HW vDPA on OVS-DPDK 方案也逐渐成熟中,其实现会更加复杂、但功能也更加完备。值得期待。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SCSI接口
    +关注

    关注

    0

    文章

    19

    浏览量

    10475
  • 虚拟机
    +关注

    关注

    1

    文章

    902

    浏览量

    28001
  • VLAN技术
    +关注

    关注

    0

    文章

    45

    浏览量

    6370
  • VMM
    VMM
    +关注

    关注

    0

    文章

    11

    浏览量

    10043
  • qemu
    +关注

    关注

    0

    文章

    57

    浏览量

    5318

原文标题:详解:VirtIO Networking 虚拟网络设备实现架构

文章出处:【微信号:SDNLAB,微信公众号:SDNLAB】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    linux设备virtio组织关系及设备初始化调用流程

    virtio_net.c,virtio_blk.c,virtio_balloon.c等这些。那么这些文件是什么关系呢?其次里面很多还有各自probe函数,到底是如何调用的,例如以网络
    的头像 发表于 09-25 15:47 4621次阅读
    linux<b class='flag-5'>设备</b>中<b class='flag-5'>virtio</b>组织关系及<b class='flag-5'>设备</b>初始化调用流程

    virtio I/O通信流程及设备框架的实现

    virtio 是一种通用的半虚拟化的 I/O 通信协议,提供了一套前后端 I/O 通信的的框架协议和编程接口。根据该协议实现设备通过前后端的配合,相比全模拟
    的头像 发表于 03-10 13:37 6308次阅读

    外网访问家里的网络设备

    网络设备
    学习电子知识
    发布于 :2023年07月17日 20:06:18

    各类网络设备

    ` 网络设备,锐捷,艾泰,D-link,华为,H3C,思科,韩电,安普`
    发表于 11-29 11:15

    Linux常用网络设备

    网络设备是计算机体系结构中必不可少的一部分,处理器如果想与外界通信,通常都会选择网络设备作为通信接口。众所周知,在 OSI(Open Systems Interconnection,开放网际互连)中,网络被划分为七个层次,从下到
    发表于 07-25 07:37

    怎么实现智能网络设备开发中的硬件的设计?

    怎么实现智能网络设备开发中的硬件的设计?
    发表于 05-26 06:47

    StratoVirt 的 virtio-blk 设备是如何实现的?

    平台下虚拟磁盘的一种实现方式,本质上为一种半模拟技术。virtio-blk 设备中采用 io_event_fd 进行前端到后端通知,采用中断注入方式
    发表于 06-29 10:37

    StratoVirt 中的虚拟网卡是如何实现的?

    的核,不停的对共享环进行轮训操作,解决了 Vhost-net 存在的问题。接下来分别介绍每种虚拟网卡是如何实现的。Virtio-netVirtio-net 是一种虚拟的以太网卡,通过
    发表于 08-10 11:16

    网络设备监管系统的设计与实现

    网络设备监管是指对IP 网络中的关键设备进行实时监控和管理,使网络管理员对网络设备的使用情况有更为深入的了解。在研究分析
    发表于 06-23 13:33 24次下载

    家用网络设备简介

    家用网络设备简介 就在几年前,家用网络设备还相当简单。使用一根直连电缆、一部网络集线器或以太网路由器,您可以将两部或多部计算机连接在一起,共享外设、
    发表于 08-05 10:26 1048次阅读

    系统虚拟化技术virtio总体设计思想

    ,主要有计算资源,存储资源和网络资源。所以,系统虚拟化技术又可以细分为计算虚拟化,存储虚拟化和网络虚拟
    的头像 发表于 05-07 15:40 4793次阅读
    系统<b class='flag-5'>虚拟</b>化技术<b class='flag-5'>virtio</b>总体设计思想

    探究I/O虚拟化及Virtio接口技术(上)

    I/O虚拟化是SmartNIC/DPU/IPU中最核心的部分,AWS NITRO就是从I/O硬件虚拟化开始,逐渐开启了DPU这个新处理器类型的创新。而Virtio接口,已经是事实上的云计算虚拟
    的头像 发表于 04-04 16:54 3733次阅读
    探究I/O<b class='flag-5'>虚拟</b>化及<b class='flag-5'>Virtio</b>接口技术(上)

    探究I/O虚拟化及Virtio接口技术(下)

    I/O虚拟化是SmartNIC/DPU/IPU中最核心的部分,AWS NITRO就是从I/O硬件虚拟化开始,逐渐开启了DPU这个新处理器类型的创新。而Virtio接口,已经是事实上的云计算虚拟
    的头像 发表于 04-04 17:03 2594次阅读
    探究I/O<b class='flag-5'>虚拟</b>化及<b class='flag-5'>Virtio</b>接口技术(下)

    panabit加载virtio网卡驱动

    引言:Panabit网络流量管理系统是一款强大的企业级网络管理软件,它提供了丰富的功能和灵活的配置选项。而virtio网卡作为一种高性能的虚拟网络设
    的头像 发表于 11-17 11:13 1051次阅读

    适用于基于FPGA的网络设备的IEEE 1588透明时钟架构

    在基于FPGA的网络设备中,精确的时间同步至关重要。虹科IEEE1588标准定义的精确时间协议(PTP)为网络中的设备提供了纳秒级的时间同步。本文将介绍虹科提供的适用于基于FPGA的网络设备
    的头像 发表于 11-23 08:04 723次阅读
    适用于基于FPGA的<b class='flag-5'>网络设备</b>的IEEE 1588透明时钟<b class='flag-5'>架构</b>