IO半虚拟化-vhost学习笔记

参考:系《深入浅出dpdk》学习笔记以及redhat的官方博客

vhost属于virtio-net网络设备的后端驱动,经历了从virtio-net后端,到内核态vhost-net,到vhost-user的演进过程。先过一下背景知识,

背景知识

QEMU

QEMU 是一个托管虚拟机模拟器,它为客户机提供了一组不同的硬件和设备模型。对于主机,qemu 表现为由标准 Linux 调度程序调度的常规进程,具有自己的进程内存。在此过程中,QEMU为客户机分配内存(被客户机视为物理内存),并执行虚拟机的CPU指令。

要在存储或网络等裸机硬件上执行 I/O,CPU 必须与物理设备交互,执行特殊指令并访问特定内存区域(例如设备映射到的内存区域)。

当客户机(虚拟机)访问这些内存区域时,控制权将返回给 QEMU,QEMU 以对客户机透明的方式执行设备的模拟。

ps:什么叫做对客户机透明呢?比如:当客户机访问由虚拟设备提供的共享内存区域时,这些访问请求实际上被QEMU截获,并由 QEMU处理。然而,客户机认为它直接在与物理设备交互,并不需要知道底层的实际处理过程。

KVM

KVM(Kernel-based Virtual Machine)是Linux内置的一项开源虚拟化技术,为虚拟化软件提供硬件辅助,利用内置的CPU虚拟化技术减少虚拟化开销(缓存、I/O、内存),提高安全性。

借助 KVM,QEMU 只需创建一个具有处理器可识别的虚拟 CPU (vCPU) 的虚拟机,即可运行本机速度的指令。当 KVM 遇到特殊指令(例如与设备交互的指令或特殊内存区域)时,vCPU 会暂停并通知 QEMU 暂停的原因,从而允许虚拟机管理程序对该事件做出反应。

QEMU是如何与KVM通信的呢,QEMU打开 /dev/kvm 设备文件,这是与 KVM 内核模块通信的接口。并使用 ioctl(输入输出控制)系统调用与 KVM 设备通信,比如调用ioctl创建一个新的虚拟机实例,添加vCPU、添加内存(由qemu 分配,但从虚拟机的角度来看是物理内存),QEMU可以通过ioctl 调用向vCPU 发送中断,就像外部设备发送中断一样。

其中一个 ioctl 调用会启动实际的 KVM vCPU。这会阻塞 QEMU 进程,使 vCPU 运行,直到遇到需要硬件协助的指令为止。但是当 vCPU 遇到需要硬件协助的指令时,ioctl 调用返回(这被称为 vmexit,虚拟机退出),由QEMU接管,比如IO操作。

QEMU与virtio-net

virtio-net后端驱动程序的最基本要素是虚拟队列机制、消息通知机制和中断机制。

  • 虚拟队列机制:连接着客户机和宿主机的数据交互
  • 消息通知机制:主要用于从客户机到宿主机的消息通知
  • 中断机制:主要用于从宿主机到客户机的中断请求和处理

在这里插入图片描述
图片来源:https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net

这个图片描述的太清晰了,先看一下什么是数据通路和控制通路:

  • 数据通路:virtio 驱动程序必须能够分配内存区域,以便管理程序和设备都可以访问这些内存区域进行读写,即通过内存共享。我们将使用这些内存区域的数据通信部分称为数据平面
  • 控制通路:设置这些内存区域的过程称为控制平面。

接下来再看下数据交互的过程:

virtio 网络设备是一个虚拟以太网卡,它支持TX/RX多队列。空缓冲区被放置在N 个virtqueue 中以接收数据包,而传出的数据包则被排队到另外N个virtqueue 中进行传输。另一个virtqueue 用于数据平面之外的驱动程序-设备通信,例如控制高级过滤功能、mac 地址等设置或活动队列的数量。作为物理 NIC,virtio 设备支持许多卸载等功能,并可以让真实主机的设备执行这些功能。

要发送数据包,驱动程序会向设备发送一个缓冲区,其中包含元数据信息(例如数据包所需的卸载),然后是要传输的数据包帧。驱动程序还可以将缓冲区拆分为多个收集条目,例如,它可以将元数据标头与数据包帧拆分开来。

这些缓冲区由驱动程序管理并由设备映射。在这种情况下,设备位于虚拟机管理程序“内部”。由于虚拟机管理程序 (qemu) 可以访问所有客户机的内存,因此它能够定位缓冲区并读取或写入它们。

以下流程图显示了 virtio-net 设备配置以及使用 virtio-net 驱动程序发送数据包的过程,该驱动程序通过 PCI 与 virtio-net 设备进行通信。在填满要发送的数据包后,它利用消息通知机制,触发“可用缓冲区通知”,将控制权返回给 QEMU,以便它可以通过 TAP(内核中的虚拟以太网设备)设备发送数据包。

然后,Qemu 通知客户机缓冲区操作(读取或写入)已完成,它通过将数据放入 virtqueue 并发送已使用通知事件来实现这一点,从而触发客户机 vCPU 中的中断。

接收数据包的过程与发送数据包的过程类似。唯一的区别是,在这种情况下,空缓冲区由客户机预先分配并提供给设备,以便设备可以将传入数据写入其中。
在这里插入图片描述
但是在这个模型中,由于宿主机、客户机和qemu之间的上下文频繁切换带来的多次数据拷贝和CPU切换,导致性能不尽如人意。可以看出,性能瓶颈处要体现在:

  • 数据通路,从TAP设备到qemu的报文拷贝和qemu到客户机的报文拷贝,两次报文拷贝导致报文接受和发送上都有性能瓶颈
  • 消息通知路径,报文到达tap设备时内核发出并送到qemu的通知信息,然后qemu利用ioctl向kvm请求中断,kvm发送中断到客户机,复杂的路径带来了不必要的性能开销。

vhost协议

Linux内核态vhost-net

为了对上述报文收发性能瓶颈进行优化,LInux内核设计了vhost-net模块,目的是通过卸载virtio-net在报文收发处理上的工作,使qemu从virtio-net的虚拟队列工作中解放处理,减少上下文切换数据包拷贝,进而提高报文收发的性能。除此之外,宿主机上的vhost-net模块还需要承担报文到达和发送消息通知及中断的工作。
在这里插入图片描述
如图所示,主要差异有两方面:

  • 数据通路:从tap设备接受数据报文,通过vhost-net模块把该报文拷贝到虚拟队列中的数据区,从而使客户机接收报文。
  • 消息通路:当报文从tap设备到达vhost-net时,通过KVM模块向客户机发送中断,通知客户机接收报文。如下图(发送通路):

在这里插入图片描述
图片来源:https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net

ps:eventfd是一种轻量级的 IPC(进程间通信方式) 执行方式。虽然 Unix 套接字允许发送和接收任何类型的数据,但 eventfd 只是一个整数,生产者可以更改,消费者可以轮询和读取。这使得它们更适合用作等待/通知机制,而不是信息传递。

vhost-net与OVS(联网)

客户机可以使用 Tap 设备与主机通信,但问题仍然是如何与同一主机上的其他虚拟机或主机外部的机器通信(例如:通过互联网)

我们可以使用内核网络堆栈提供的任何转发或路由机制(如标准 Linux 桥接器)来实现这一点。但是,更高级的解决方案是使用完全虚拟化、分布式、可管理的交换机,例如开放虚拟交换机(OVS)。

OVS datapath 在此场景中作为内核模块运行,ovs-vswitchd 作为用户空间控制和管理守护进程,ovsdb-server 作为转发数据库。

如下图所示,OVS datapath 在内核中运行,负责在物理网卡和虚拟TAP设备之间转发数据包:

在这里插入图片描述

用户态vhost

首先我们了解一下:DPDK 提供了一系列轮询模式驱动程序 (PMD),可实现用户空间和物理接口之间的数据包直接传输,从而完全绕过内核网络堆栈。通过消除中断处理和绕过内核堆栈,这种方法比内核转发显著提高了性能。
在这里插入图片描述
图片来源:https://www.redhat.com/en/blog/how-vhost-user-came-being-virtio-networking-and-dpdk

Linux内核态的vhost-net模块需要在内核态完成报文拷贝和消息处理,这会给报文处理带来一定的性能损失,于是就有了用户态的vhost,用户态vhost采用了共享内存技术,通过共享的虚拟队列来完成报文传输和控制,大大降低了vhost和virtio-net之间的数据传输成本。由于报文拷贝是在用户态进行,因此Linux内核的负担得到减轻。
而virtio/vhost又是如何和dpdk交互的呢?

vhot-user/virtio-pmd 架构

virtio 在主机用户空间和客户机用户空间都使用 DPDK,如图所示:
在这里插入图片描述

  • vhost-user(后端) - 作为 OVS-DPDK 用户空间应用程序的一部分在主机用户空间上运行。如前所述,DPDK 是一个库,而 vhost-user 模块是该库内的附加 API。OVS-DPDK 是与此库链接并调用 API 的实际应用程序。对于在主机上创建的每个客户机 VM,将实例化另一个 vhost-user 后端以与客户的 virtio 前端进行通信。

  • virtio-pmd(前端) - 在客户用户空间上运行,是一个轮询模式驱动程序,使用专用核心并执行无中断轮询。对于在用户空间上运行的应用程序,要使用 virtio-pmd,它还需要与 DPDK 库链接。

如果我们将这种架构与基于内核的 vhost-net/virtio-net 架构进行比较,vhost-net 被 vhost-user 取代,而 virtio-net 被 virtio-pmd 取代。

通过使主机用户空间能够通过共享内存绕过内核直接访问物理 NIC,并且通过在客户机用户空间上使用 virtio-pmd 也绕过内核,整体性能可以提高 2 到 4 倍。

然而,这在可用性方面是有代价的。在 vhost-net/virtio-net 架构中,从客户操作系统的角度来看,数据平面通信非常简单:只需将 virtio 驱动程序添加到客户内核,客户用户空间应用程序就会自动获得一个标准的 Linux 网络接口来工作。

相比之下,在 vhost-user/virtio-pmd 架构中,客户用户空间应用程序需要使用 virtio-pmd 驱动程序(来自 DPDK 库)来优化数据平面。实现比较复杂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/380580.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

几种常用排序算法

1 基本概念 排序是处理数据的一种最常见的操作,所谓排序就是将数据按某字段规律排列,所谓的字段就是数据节点的其中一个属性。比如一个班级的学生,其字段就有学号、姓名、班级、分数等等,我们既可以针对学号排序,也可…

huawei USG6001v1学习---防火墙高可靠性(双机热备)

1.什么是双机热备 如图:当左图的防火墙发生故障时,整个系统都会收到影响,而右图即使有防火墙发生故障,但是还有一台防火墙做备份,相对于只有一台防火墙,要可靠些。 由于防火墙上不仅需要同步配置信息&…

【Linux】—— 进程的基本概念、PCB、fork

🌏博客主页:PH_modest的博客主页 🚩当前专栏:Linux跬步积累 💌其他专栏: 🔴 每日一题 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮&#xff0…

【海外云手机】静态住宅IP集成解决方案

航海大背景下,企业和个人用户对于网络隐私、稳定性以及跨国业务的需求日益增加。静态住宅IP与海外云手机的结合,提供了一种创新的集成解决方案,能够有效应对这些需求。 本篇文章分为三个部分;静态住宅优势、云手机优势、集成解决…

Spring框架、03SpringMVC

SpringMVC SpringMVC入门 介绍 SpringMVC将Servlet一些通用功能进行了抽取和封装,使用它之后,代码主要有两部分组成: 前端控制器:由SpringMVC提供,主要负责接收参数和返回数据 处理器:由程序员编写&…

好用的接口文档swagger

本篇文章记录怎么给我们的后端项目整一个好用的接口文档 这个东西好像叫什么swagger吧 1. 依赖引入&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId></dependency>…

AWE2025正式启动,AWE×AI 推动智慧生活的普及

7月18日&#xff0c;2025年中国家电及消费电子博览会&#xff08;AWE2025&#xff09;正式启动。主办方宣布&#xff0c;AWE2025的主题为“AI科技、AI生活”&#xff0c;展会将于2025年3月20-23日在上海新国际博览中心举办。 作为全球三大家电和消费电子领域展会之一&#xff…

图书馆定位导航:RFID、VR与AR技术在图书馆中的应用

图书馆作为知识的宝库&#xff0c;承载着无数求知者的梦想与期待&#xff0c;随着馆藏书籍数量的激增与图书馆布局的日益复杂&#xff0c;读者在寻找目标书籍往往有许多困难。传统的索引号查询方式虽能提供书籍的基本信息&#xff0c;但在寻找过程中&#xff0c;因不熟悉图书馆…

各种复现,保证质量

代码复现&#xff0c;文献复现&#xff0c;模型复现&#xff0c;算法复现&#xff0c;文章复现&#xff0c;创新点等等&#xff0c;python/matlab/c语言/r语言均可&#xff0c;保证高质量完成&#xff0c;可接急单&#xff0c;不成功不收费&#xff01;

Apache Bigtop 正式支持 openEuler,共创大数据新生态

近日&#xff0c;在OpenAtom openEuler&#xff08;简称"openEuler"&#xff09;BigData SIG与Linaro的携手努力下&#xff0c;** Apache Bigtop于2024年7月8日发布的3.3.0新版本中&#xff0c;正式宣告了对openEuler操作系统的原生支持**。这一里程碑式的进展&#…

人话讲下如何用github actions编译flutter应用-以编译windows为例

actions的脚本看下这个&#xff0c;有简单的说明&#xff0c;有关于编译个平台的脚本&#xff1a; https://github.com/marketplace/actions/flutter-action 打开你要编译的项目点击那个Actions按钮 然后随便点击一个脚本会跳到白框编辑界面 打开上文提到的网址随便抄下就ok …

前端-04-VScode敲击键盘有键入音效,怎么关闭

目录 问题解决办法 问题 今天正在VScode敲项目&#xff0c;不知道是按了什么快捷键还是什么的&#xff0c;敲击键盘有声音&#xff0c;超级烦人啊&#xff01;&#xff01;于是我上网查了一下&#xff0c;应该是开启了VScode的键入音效&#xff0c;下面是关闭键入音效的办法。…

Go语言并发编程-Goroutine调度

goroutine 概念 在Go中&#xff0c;每个并发执行的单元称为goroutine。通常称为Go协程。 go 关键字启动goroutine go中使用关键字 go 即可启动新的goroutine。 示例代码&#xff1a; 两个函数分别输出奇数和偶数。采用常规调用顺序执行&#xff0c;和采用go并发调用&…

Win10环境将Docker部署到非系统盘

Win10环境将Docker部署到非系统盘 目录 Win10环境将Docker部署到非系统盘 一、Docker官网客户端Docker Hub下载 二、windows环境的安装 三、正确的迁移步骤 3.1、确保你的系统分区至少3G的剩余空间&#xff1b; 3.2、默认方式安装Docker hub&#xff1b; 3.3、打开Dock…

HTML开发笔记:1.环境、标签和属性、CSS语法

一、环境与新建 在VSCODE里&#xff0c;加载插件&#xff1a;“open in browser” 然后新建一个文件夹&#xff0c;再在VSCODE中打开该文件夹&#xff0c;在右上角图标新建文档&#xff0c;一定要是加.html&#xff0c;不要忘了文件后缀 复制任意一个代码比如&#xff1a; <…

OCC 创建点线面体

目录 一、利用封装已有算法实现 1、盒子建模算法封装 2、可视化 二、利用OCC 点线面实现 1、实现过程 2、实现一个面 3、拉伸面生成体 4、旋转面生成体 三、总结 一、利用封装已有算法实现 1、盒子建模算法封装 BRepPrimAPI_MakeBox box(2, 2, 2); 2、可视化 void VTK…

基于上下文自适应可变长熵编码 CAVLC 原理详细分析

CAVLC CAVLC&#xff0c;即Context-Adaptive Variable-Length Coding&#xff0c;是一种用于视频压缩的编码技术&#xff0c;特别是在MPEG-4视频编码标准中使用。CAVLC是一种熵编码方法&#xff0c;它根据视频数据的上下文信息来调整编码长度&#xff0c;以实现更有效的数据压…

Stable Diffusion 使用详解(2)---- 图生图原理,操作,参数

目录 背景 图生图原理 基本原理 1. 扩散模型基础 2. 图生图的具体流程 3. 关键技术点 4. 应用实例 CLIP 原理 1.基本概念 2. 核心特点 使用及参数 随机种子 重绘幅度 图像宽高 采样方法 1. DPM&#xff08;扩散概率模型&#xff09; 2. SDE&#xff08;随机微…

5G mmWave PAAM 开发平台

Avnet-Fujikura-AMD 5G 毫米波相控阵天线模块开发平台 Avnet 和 Fujikura 为毫米波频段创建了一个领先的 5G FR2 相控阵天线开发平台。该平台使开发人员能够使用 AMD Xilinx 的 Zynq UltraScale™ RFSoC Gen3 和 Fujikura 的 FutureAcess™ 相控阵天线模块 (PAAM) 快速创建和制…

【项目】星辰博客介绍

目录 一、项目背景 二、项目功能 1. 登录功能&#xff1a; 2. 列表页面&#xff1a; 3. 详情页面&#xff1a; 4. 写博客&#xff1a; 三、技术实现 四、功能页面展示 1. 用户登录 2. 博客列表页 3. 博客编辑更新页 4.博客发表页 5. 博客详情页 五.系统亮点 1.强…