IO半虚拟化-Virtio学习笔记

参考:《深入浅出DPDK》及大佬们的各种博客

Virtio简介&运行环境

Virtio 是一种用于虚拟化环境中的半虚拟化 I/O 框架,目的是在虚拟机和主机之间提供一种高效的 I/O 机制。关于什么是半虚拟化和全虚拟化:见SR-IOV学习笔记。
YES,virtio 是作为客户机访问主机上的设备的接口而开发的,因此可以分为两部分:

  • virtio Guest OS(虚拟机)中实现的前端程序,定义了如何在客户机和主机之间创建控制平面和数据平面
  • vhost 协议,在宿主机(物理机或主机)实现的后端驱动, 允许将 virtio 数据平面实现外置到另一部分(用户进程或内核模块)以提高性能的协议,核心目的是通过将虚拟设备的数据处理任务从虚拟机监视器(如 QEMU)转移到主机上的用户态或内核态进程
    ps:大家伙耳熟能详(呃,或许并不太熟悉)的virtio-net是虚拟以太网卡,是一种virtio支持的IO设备。

Virtio 被广泛应用于 KVM(Kernel-based Virtual Machine)和 QEMU 等虚拟化平台,提供了包括网络、块设备等在内的多种虚拟设备支持。其工作环境如下:
在这里插入图片描述
图片来源:https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net

下面浅谈下Virtio的同事们:

  • KVM

    • 个人简介:基于Linux内核的开源虚拟化解决方案
    • 工作团队:内核空间
    • 工作内容:提供虚拟化支持,允许在同一台物理机上运行多个操作系统作为虚拟机,实现硬件资源的高效利用和灵活管理,相当于把 Linux 内核转变为虚拟机管理程序,使得虚拟机可以直接利用硬件虚拟化扩展(如 Intel VT-x 和 AMD-V)运行。
  • QEMU

    • 个人简介:通用且开源的虚拟机模拟器和虚拟化工具
    • 工作团队:用户空间
    • 工作内容:1. 模拟整个计算机系统,包括处理器、内存、硬盘、网络接口等, 适用于运行不同架构的完整操作系统(比如在x86系统上运行ARM, 斗宗强者,竟恐怖如斯) 2. 提供虚拟化支持,可以利用硬件虚拟化技术(如 Intel VT-x 和 AMD-V)运行虚拟机,大大的提高性能。
  • Libvirt

    • 个人简介:虚拟化技术管理员
    • 工作团队:用户空间
    • 工作内容:1. 调用qemu创建、启动、恢复、暂停虚拟机,是真正的虚拟机管理者,并提供API供用户调用 2. 为每个虚拟机启动一个 qemu 进程,并将 XML 格式的配置转换为 qemu CLI 调用的接口,供用户使用

半虚拟化Virtio

Virtio使用场景

在现代数据中心中大量采用虚拟化技术,IO全虚拟方案中,虚拟机以寄存器的方式访问外设,比如网卡发送一个报文,需要写很多次寄存器,造成大量的(VM-exit,虚拟机暂停运行),性能很差。IO透传方案性能很好,但不能从硬件上支持虚拟机的动态迁移以及缺乏足够灵活的流分类规则。于是,就有了很多Vritio的使用场景。其实现有的云计算厂商,很多都是用的virtio实现的虚拟机和裸金属场景的热迁移。

以下是virio设备的典型场景
在这里插入图片描述
宿主机使用虚拟交换机联通物理网卡和虚拟机。虚拟交换机内部有DPDK vhost,实现了Virtio的后端网络设备驱动程序逻辑,虚拟机里有DPDK的前端网络设备驱动。前端和后端通过virtio的虚拟队列交换数据。
这样虚拟机中的网络数据遍剋发送到虚拟交换机中,通过转发逻辑,经由物理网卡进入外部网络。

Virtio架构&原理

Virtio架构如下图所示,
在这里插入图片描述

  • 前端驱动程序

    • 包含不同前端驱动程序,如块设备(例如磁盘)驱动、网络设备驱动等驱动程序。每个前端驱动程序在虚拟机管理程序中都有相应的后端驱动程序。 驱动程序可以根据需要使用零个或多个队列。例如,virtio网络驱动程序使用两个虚拟队列(一个用于接收,一个用于发送),而virtio块驱动程序仅使用一个。虚拟队列是虚拟的,实际上被实现为环以遍历客户机到虚拟机管理程序的转换。
  • 虚拟队列

    • 连接客户机操作系统 和宿主机后端驱动的实际数据链路

虚拟队列

虚拟队列主要由描述符列表(descriptor table)、可用换标和已用环表(used ring)组成。描述符列表指向的是实际要传输的数据。两个环表指向的是描述符列表,分别用来标记前端和后端驱动程序对描述符列表中描述符的处理进度。详细来看:

  • 描述符列表
/* dpdk/drivers/net/virtio/virtio_ring.h */
struct vring_desc {uint64_t addr;  /*  数据缓冲区的客户机物理地址 */uint32_t len;   /* 数据缓冲区的长度 */uint16_t flags; /* 标志位,表示当前描述符的书香,如next是否有效等 */uint16_t next;  /* 描述符链中下一个描述符的地址 */
};
  • 可用环表
/* dpdk/drivers/net/virtio/virtio_ring.h */
struct vring_avail {uint16_t flags;		/* 标志位,表示环表的一些属性,比如是否需要设备在使用了环表中的表项后发送中断给驱动 */uint16_t idx;		/* 驱动写入下一个可用描述符的位置 */uint16_t ring[0];   /* 存储描述符指针(id)的数组 */
};
  • 已用环表
/* dpdk/drivers/net/virtio/virtio_ring.h */
struct vring_used_elem {/* Index of start of used descriptor chain. */uint32_t id;/* Total length of the descriptor chain which was written to. */uint32_t len;
};struct vring_used {uint16_t flags;			/* 标志位,包括是否需要驱动在回收了已用环表中的表项后发送提醒给设备  */volatile uint16_t idx;struct vring_used_elem ring[0];
};

Virtio设备的使用

设备的使用主要包括两部分:

  • 驱动通过描述符列表和可用环表提供的数据缓冲区给设备用
    • 把数据缓冲区地址、长度等信息赋值到空闲的描述符中
    • 把改描述符指针添加到该虚拟队列的可用环表的头部
    • 更新可用环表中的头部指针
    • 写入该虚拟队列编号到Queue Notify寄存器以通知设备
  • 设备使用描述符后再通过已用环表还给驱动
    • 把使用过的数据缓冲区描述符的头指针添加到该虚拟队列的已用环表的头部
    • 更新该已用环表的头部指针
    • 根据是否开启MSI-X中断,用不同的中断方式通知驱动。

Virtio网络设备

virtio网络设备Linux驱动主要包括三部分:

  • 底层PCI-e设备层
    • 负责监测PCI-e设备,并初始化设备对应的驱动程序
  • 中间Virtio虚拟队列层
    • 实现了Virtiio协议中的虚拟队列
  • 上层网络设备层
    • 实现了两个抽象类:virtio设备和网络设备,从而Linux系统能够对待普通网卡一样操作这个virtio网络设备
/* dpdk/lib/librte_vhost/rte_virtio_net.h  */
/*** Device and vring operations.*/
struct virtio_net_device_ops {int (*new_device)(int vid);		/**< Add device. */void (*destroy_device)(int vid);	/**< Remove device. */int (*vring_state_changed)(int vid, uint16_t queue_id, int enable);	/**< triggered when a vring is enabled or disabled */void *reserved[5]; /**< Reserved for future extension */
};

以上,顺心顺意!

参考:

《深入浅出dpdk》
https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net
https://developer.ibm.com/articles/l-virtio/
https://tinylab.org/virtio-intro/

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

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

相关文章

PDMS二次开发(二十二)——关于1.0.3.1版本升级内容的说明

目录 1.更新内容介绍2.效果演示3.关于重构自动添加焊口功能的说明3.1错误示例 3.问题交流1.创建焊口提示失败2.程序崩溃 1.更新内容介绍 在添加焊口之前先清除当前branch已有焊口&#xff1b;显示清除焊口的个数和添加焊口的个数&#xff1b;重构了自动添加焊口功能&#xff0…

值得关注的数据资产入表

不错的讲解视频&#xff0c;来自&#xff1a;第122期-杜海博士-《数据资源入表及数据资产化》-大数据百家讲坛-厦门大学数据库实验室主办第122期-杜海博士-《数据资源入表及数据资产化》-大数据百家讲坛-厦门大学数据库实验室主办-20240708_哔哩哔哩_bilibili

《A++ 敏捷开发》- 10 二八原则

团队成员协作&#xff0c;利用项目数据&#xff0c;分析根本原因&#xff0c;制定纠正措施&#xff0c;并立马尝试&#xff0c;判断是否有效&#xff0c;是改善的“基本功”。10-12章会探索里面的注意事项&#xff0c;13章会看两家公司的实施情况和常见问题。 如果已经获得高层…

java中的String 以及其方法(超详细!!!)

文章目录 一、String类型是什么String不可变的原因(经典面试题)String不可变的好处 二、String的常用构造形式1.使用常量串构造2.使用newString对象构造3.字符串数组构造 三、常用方法1. length() 获取字符串的长度2. charAt() 获取字符串中指定字符的值 (代码单元)3. codePoin…

水的几个科学问题及引发的思考

水的几个科学问题及引发的思考 两个相同的容器A和B&#xff0c;分别装有同质量的水&#xff0c;然后&#xff0c;在A容器中加入水&#xff0c;在B容器中加入冰&#xff0c;如果加入水和冰的质量相同。问&#xff0c;容器B的水位将与容器A的水位相同吗&#xff08;假设冰未融化时…

【ZooKeeper学习笔记】

1. ZooKeeper基本概念 Zookeeper官网&#xff1a;https://zookeeper.apache.org/index.html Zookeeper是Apache Hadoop项目中的一个子项目&#xff0c;是一个树形目录服务Zookeeper翻译过来就是动物园管理员&#xff0c;用来管理Hadoop&#xff08;大象&#xff09;、Hive&…

AR0132AT 1/3 英寸 CMOS 数字图像传感器可提供百万像素 HDR 图像处理(器件编号包含:AR0132AT6R、AR0132AT6C)

AR0132AT 1/3 英寸 CMOS 数字图像传感器&#xff0c;带 1280H x 960V 有效像素阵列。它能在线性或高动态模式下捕捉图像&#xff0c;且带有卷帘快门读取。它包含了多种复杂的摄像功能&#xff0c;如自动曝光控制、开窗&#xff0c;以及视频和单帧模式。它适用于低光度和高动态范…

QML界面控件加载与显示顺序

一、QML界面控件加载顺序 QML在界面加载时的顺序和我们认知的有很大的不同&#xff0c;有时候会对我们获取参数以及界面实现造成很大的困扰 1、加载顺序 import QtQuick 2.12 import QtQml 2.12 import QtQuick.Window 2.12 import QtQuick.VirtualKeyboard 2.4Window {id: …

九盾安防:如何调控叉车限速器的报警速度呢

在繁忙的物流仓储和制造业环境中&#xff0c;叉车是不可或缺的搬运设备。然而&#xff0c;其高速行驶也带来了潜在的安全隐患。为了确保作业人员和货物的安全&#xff0c;又车限速器的设置显得尤为关键。那么&#xff0c;如何调控叉车限速器的报警速度呢? 叉车限速器的速度调整…

复制vmware虚拟机文件并改名(文件名使用python替换)得到一台新的虚拟机

文章目录 需求实验复制文件夹并重命名使用python将所有文件名“WinSer2022”字符替换成“wingetmac”修改虚拟机配置文件&#xff08;.vmx&#xff09;打开新的虚拟机成功 需求 将已有的Winser2022虚拟机复制成wingetmac并开机 实验 复制文件夹并重命名 将"WinSer2022…

了解并缓解 IP 欺骗攻击

欺骗是黑客用来未经授权访问计算机或网络的一种网络攻击&#xff0c;IP 欺骗是其他欺骗方法中最常见的欺骗类型。通过 IP 欺骗&#xff0c;攻击者可以隐藏 IP 数据包的真实来源&#xff0c;使攻击来源难以知晓。一旦访问网络或设备/主机&#xff0c;网络犯罪分子通常会挖掘其中…

1559. 二维网格图中探测环

1559. 二维网格图中探测环 给你一个二维字符网格数组 grid &#xff0c;大小为 m x n &#xff0c;你需要检查 grid 中是否存在 相同值 形成的环。 一个环是一条开始和结束于同一个格子的长度 大于等于 4 的路径。对于一个给定的格子&#xff0c;你可以移动到它上、下、左、右…

【Qt 初识】QPushButton 的详解以及 Qt 中的坐标

文章目录 1. Qt 中的信号槽机制 &#x1f34e;2. 通过图形化界面的方式实现 &#x1f34e;3. 通过纯代码的方式实现按钮版的HelloWorld &#x1f34e;4. 设置坐标 &#x1f34e; 1. Qt 中的信号槽机制 &#x1f34e; 》&#x1f427; 本质就是给按钮的点击操作&#xff0c;关联…

GuLi商城-商品服务-API-品牌管理-OSS获取服务端签名(续)

如何进行服务端签名直传_对象存储(OSS)-阿里云帮助中心 gulimall-third-party服务的代码: package com.nanjing.gulimall.thirdparty.controller;import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.utils.BinaryUtil; impor…

Linux开发:Fuse介绍

Fuse(filesystem in userspace),是一个用户空间的文件系统。通过fuse内核模块的支持&#xff0c;开发者只需要根据fuse提供的接口实现具体的文件操作时所对应的回调函数&#xff0c;就可以实现一个文件系统。由于其主要实现代码位于用户空间中&#xff0c;因此不需要重新编译内…

15 - matlab m_map地学绘图工具基础函数 - 一些数据转换函数(二)

15 - matlab m_map地学绘图工具基础函数 - 一些数据转换函数&#xff08;二&#xff09; 0. 引言1. 关于m_geodesic2. 关于mygrid_sand23. 结语 0. 引言 通过前面篇节已经将m_map绘图工具中大多绘图有关的函数进行过介绍&#xff0c;已经能够满足基本的绘图需求&#xff0c;本节…

个人倒计时页面源码,实用倒计时单页源码

一、源码描述 这是一款非常实用的个人倒计时页面&#xff0c;支持设置未来一年时间&#xff0c;支持设置背景音乐&#xff0c;支持自定义下拉页面&#xff0c;点击向下箭头查看。 二、源码截图 三、源码下载

深入探讨【C++容器适配器】:现代编程中的【Stack与Queue】的实现

目录 一、Stack&#xff08;栈&#xff09; 1.1 Stack的介绍 1.2 Stack的使用 1.3 Stack的模拟实现 二、Queue&#xff08;队列&#xff09; 2.1 Queue的介绍 2.2 Queue的使用 2.3 Queue的模拟实现 三、容器适配器 3.1 什么是适配器 3.2 为什么选择deque作为stack和…

基于Vue和UCharts的前端组件化开发:实现高效、可维护的词云图与进度条组件

基于Vue和UCharts的前端组件化开发&#xff1a;实现高效、可维护的词云图与进度条组件 摘要 随着前端技术的迅速发展和业务场景的日益复杂&#xff0c;传统的整块应用开发方式已无法满足现代开发的需求。组件化开发作为一种有效的解决方案&#xff0c;能够将系统拆分为独立、…

解决pycharm无法识别miniconda

解决pycharm无法识别miniconda 找到miniconda安装目录下condabin/conda.bat文件&#xff0c;点击load即可识别codna环境 a环境