Virtio原理简介
目录
Virtio规范简介
相关数据结构
Vring机制简介
相关文章
实现IO虚拟化主要有三种方式:全虚拟化、半虚拟化和透传。全虚拟化Guest OS不会感知到自己是虚拟机,也无需修改Guest OS,但是它的效率比较低。半虚拟化Guest OS知道自己是虚拟机,通过Frontend/Backend驱动模拟实现IO虚拟化。透传就是直接分配物理设备给VM用。Virtio是一种半虚拟化的设备抽象接口规范,在Qemu和KVM中得到了广泛使用,本文将简单介绍Virtio的基本原理。
代码版本
- Qemu
- qemu-2.10.1
- Kernel
- kernel-3.10.0
Virtio SPEC
- Virtual I/O Device (VIRTIO) Version 1.0
- http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html
- Virtio PCI Card Specification Version 0.9.5
- http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
Virtio在Guest中实现了前端驱动,在Host中实现了后端驱动,前后端之间通过Virtqueue(虚拟队列)交换数据,Host中会使用后端驱动程序模拟一个PCI设备,因此也称前端驱动为Driver,后端驱动为Device。Guest在Host OS上表示为一个Qemu的进程,Guest OS的pa实际上也属于Host OS的地址空间,因此Virtio采用的Virtqueue的方式来避免了Guest和Host间数据的复制。下面先介绍一下Virtio,更为详细的描述请阅读前言中提供的Virtio SPEC文档,那里是最准确而详细的描述,在此仅简单介绍一下后文需要用到的概念。
Virtio规范简介
Basic Facilities of a Virtio Device
每个Virtio设备包括以下部分
- Device status field 设备状态字段
- Feature bits 特征位
- Device Configuration space 设备配置空间
- One or more virtqueues 一个或多个virtqueues
virtqueues
在virtio设备上进行批量数据传输的机制被称为virtqueue,每个设备可以拥有零个或多个virtqueue,每个virtqueue由三部分组成:
- Descriptor Table
- Available Ring
- Used Ring
每部分在客户机内存中是物理连续的,并且有不同的对齐要求,virtqueue的每个部分的内存对齐和大小要求如下表,其中Queue Size对应virtqueue中的最大buffer数,始终为2的n次幂,以特定于总线的方式指定:
Virtqueue Part | Alignment | Size |
---|---|---|
Descriptor Table | 16 | 16*(Queue Size) |
Available Ring | 2 | 6 + 2*(Queue Size) |
Used Ring | 4 | 6 + 8*(Queue Size) |
Descriptor Table指的是Driver用于Device的缓冲区,由Queue Size个Descriptor组成。Descriptor中存有GPA的字段addr,长度字段len,可以链接next Descriptor的next指针等(形成描述符链)。如果协商了VIRTIO_F_INDIRECT_DESC feature则可以使用Indirect Descriptors来增加ring的容量。
Available Ring中的每个条目是一个是描述符链的头部,它仅由Driver写入并由Device读取,Device获取Descriptor后,Descriptor对应的缓冲区可能是可读的也可能是可写的,可读的用于Driver发送数据,可写的用于接收数据。
Used Ring的介绍直接贴SPEC文档中的描述上来比翻译过来更容易理解。The used ring is where the device returns buffers once it is done with them: it is only written to by the device,and read by the driver.简单来说Used Ring的作用就是Device使用完Descriptor之后,将Descriptor放入这里,通知Driver回收。
相关数据结构
一些数据结构只列举了部分关键信息
如图所示,virtnet_info作为virtio网络设备的私有数据将virtio_device和net_device链接在一起。对于virtio网络设备来说,它至少有两个virtqueue(如果协商了VIRTIO_NET_F_MQ则可以创建多个队列,详见VirtIO SPEC中5.1.2 ),一个用于TX(send_queue),另一个用于RX(receive_queue),TX和RX队列中都包含了virtqueue和scatterlist[]。virtio_device、virtnet_info、receive_queue、send_queue、virtqueue给定任一结构体均可得到其它结构体信息。
可以把virtqueue理解为一个接口类,而vring_virtqueue作为这个接口的一个实现,vring_virtqueue通过成员vq可以与上述其它struct建立联系。virtio的环形缓冲区机制是由vring来承载的,vring由三部分组成:Descriptor表(vring_desc),Available ring(vring_avail)和Used ring(vring_used)。
Vring机制简介
在virtio设备上进行批量数据传输的机制被称为virtqueue。每个设备可以拥有零个或多个virtqueue,当Driver想要向设备发送数据时,它会填充Descriptor Table中的一项(或将几项链接在一起),并将描述符索引写入Available Ring中,然后它通知Device,当Device完成后,它将描述符索引写入Used Ring中并发送中断。(详见SPEC 2.4)
下图Virtio网络设备发包过程为例讲解上述机制,Driver将sk_buffer填充进scatterlist table中(只是设置地址没有数据搬移),然后通过计算得到GPA并将GPA写入Descriptor Table中,同时将Desc chain的head记录到Available Ring中,然后通过PIO的方式通知Device,Device发包并更新Used Ring。
后续会有一篇文章专门分析发包过程
- 本文作者: Lauren
- 本文链接: http://lihanlu.cn/virtio-introduction/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
《Linux虚拟化KVM-Qemu分析(八)之virtio初探》
《Linux虚拟化KVM-Qemu分析(九)之virtio设备》
《virtio 网络的演化》
《使用DPDK打开Open vSwitch(OvS) *概述》
《Open vSwitch(OVS)文档》
《《深入浅出DPDK》读书笔记(十五):DPDK应用篇(Open vSwitch(OVS)中的DPDK性能加速)》
《virtio 网络的演化:原始virtio > vhost-net(内核态) > vhost-user(DPDK) > vDPA》
站外参考文章
《SR-IOV:网卡直通技术》
《关于英特尔® 以太网服务器适配器中 SR-IOV 的常见问题解答》
《Vhost-user详解》
Virtio原理简介相关推荐
- javascript原理_JavaScript程序包管理器工作原理简介
javascript原理 by Shubheksha 通过Shubheksha JavaScript程序包管理器工作原理简介 (An introduction to how JavaScript pa ...
- Nginx 反向代理工作原理简介与配置详解
Nginx 反向代理工作原理简介与配置详解 测试环境 CentOS 6.8-x86_64 nginx-1.10.0 下载地址:http://nginx.org/en/download.html 安装 ...
- DeepLearning tutorial(1)Softmax回归原理简介+代码详解
FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...
- DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解
FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...
- DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解
FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...
- 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )
文章目录 一.主线程中的 Handler 与 Looper 二.Handler 原理简介 一.主线程中的 Handler 与 Looper Android 系统中 , 点击图标启动一个应用进程 , 就 ...
- 量子计算机编程原理简介 和 机器学习
量子计算机编程原理简介 和 机器学习 本文翻译自D-Wave公司网站 www.dwavesys.com/en/dev-tutorial-intro.html D-wave公司在2007年就声称实现了1 ...
- DL之CNN:卷积神经网络算法简介之原理简介——CNN网络的3D可视化(LeNet-5为例可视化)
DL之CNN:卷积神经网络算法简介之原理简介--CNN网络的3D可视化(LeNet-5为例可视化) CNN网络的3D可视化 3D可视化地址:http://scs.ryerson.ca/~aharley ...
- DL之CNN:卷积神经网络算法简介之原理简介(步幅/填充/特征图)、七大层级结构(动态图详解卷积/池化+方块法理解卷积运算)、CNN各层作用及其可视化等之详细攻略
DL之CNN:卷积神经网络算法简介之原理简介(步幅/填充/特征图).七大层级结构(动态图详解卷积/池化+方块法理解卷积运算).CNN各层作用及其可视化等之详细攻略 目录 CNN 的层级结构及相关概念 ...
最新文章
- (链表)反转链表Reverse List
- Python之collections模块详细实例
- Uva 10817 校长的烦恼
- 图表中如何实现动态变更分类轴与系列值
- windows分辨率修改工具_3个修改图片DPI的方法
- Java2十大经典中文图书
- Android模拟器的模拟键盘区不见了怎么办
- Git安装包(win64)镜像下载地址
- JAVA通过poi实现excel表格制作并且将图片放入到指定的单元格中(可以循环插入)
- 宏定义 指针 c语言,C语言宏定义讲解(C和指针 笔记)
- sdh管理单元指针_SDH管理单元指针介绍.doc
- A2021-A2022年度项目总结(二)
- IDempiere 富文本编辑器优化
- 云主机上手教程:轻量应用服务器体验
- 电信机顶盒ty1208-z刷linux(armbian)
- IOS截屏的几种方法
- FTP工具,3款FTP工具推荐
- 【技巧】UITableView 在UITableViewStylePlain模型下,取消headerView的黏结性,不浮动
- oracle数据库权限
- Socket通信bind错误
热门文章
- PL/SQL Developer 8.0.2.1505 简体中文汉化版下载,带注册机-永久注册。
- 深度优先搜索之城堡问题
- springboot undertow替换tomcat方式
- iOS app submission : missing 64-bit support
- LeetCode 3sum 问题
- Socket网络编程--Libev库学习(3)
- SVG与CSS的特殊性
- 《教孩子编程(Python语言版)》课程介绍
- .mysql的配置文件是正确的,为啥启动后一查所展示的并不是自己设置的配置
- 华为p10 鸿蒙,全面上线!华为鸿蒙新消息传来,这是要彻底替换安卓