Virtio学习笔记(一):简介

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/scaleqiao/article/details/45938369

最近在做一些虚拟化方面的工作,因为其中有涉及到virtio这个部分,所以我花了点时间学习了一下这个技术。趁着知识还新鲜,也结合我从零学起的经历,在这里把我学到的东西整理出一个系列文章,跟大家分享一下,希望对大家有所帮助。目前内容主要包括:virtio简介、virtio相关架构、virtqueue学习、virtio_ring学习、virtio中blk设备的IO路径以及virtio后端这几个部分。当然我还在继续学习中,如果哪些地方写的不对也欢迎各位大牛们及时指正,免得误人子弟啊。好吧,废话少说,从virtio简介开始吧。

学习一个东西,我们得先了解它的背景,也就是它为什么会出现?virtio从其名字来看肯定是和IO相关的,它的出现肯定是为了解决IO中遇到的问题,到底是什么问题呢?要回答这些问题,就得从以下几个虚拟化名词说起了,已经有这些概念的请略过:

一个计算机系统的核心就是CPU,它运行程序代码、访问内存和外设,所以虚拟化的本质也就是实现CPU的虚拟化。从这个虚拟化实现方案的角度来看,可以分为纯软件的虚拟化方案和有硬件支持的虚拟化方案。这里的硬件支持主要是Intel的VT-x和AMD的AMD-V,他们能提供处理器级的虚拟化。当然从另外一个维度虚拟化技术又可以分为全虚拟化(full-virtualization)和准虚拟化(para-virtualization)。全虚拟化指的是虚拟机操作系统不需要做任何修改就能跑在hypervisor之上,像Qemu、VMware、VirtualBox都能提供全虚拟化方案。而准虚拟化指的是,虚拟机的操作系统要做一定的修改才能运行,比如XEN和KVM就是提供泛虚拟化的方案。

尽管KVM能够借助于物理硬件提供的CPU、内存等的虚拟化支持来提升效率,但KVM本身不提供IO设备以及虚拟机管理方面的支持,而是借助于Qemu来提供这些功能。KVM加上Qemu的组合可以为用户提供全虚拟化的解决方案,但QEMU通过纯软件的方式模拟得到的IO设备在性能上有明显问题。我们看一下Qemu的IO模型


在使用QEMU模拟I/O的情况下,当客户机中的设备驱动程序(Device Driver)发起I/O操作请求时,KVM模块(Module)中的I/O操作捕获代码会拦截此次I/O,然后经过加工处理后,将本次I/O处理请求放入I/O共享页中(sharing page),并通知用户空间的QEMU程序来模拟出本次的I/O操作。QEMU通过Linux宿主机中真正的设备驱动完成此次操作,并将操作结果放回到I/O共享页,然后通知KVM模块中的I/O操作捕获代码。当然,这一操作过程中,客户机作为QEMU的一个进程在等待I/O时可能被阻塞。另外,当客户机通过DMA访问大块内存时,QEMU模拟程序不会把操作结果放到I/O共享页中,而是通过内存映射的方式将结果直接写到客户机的内存中去,然后通过KVM模块告诉客户DMA操作完成。

在这种模型下,每次I/O操作的路径比较长,而且需要依赖KVM和Qemu这两个类似于中介角色的参与。这其中会涉及虚拟机和宿主机之间的切换(也就是VMEntry和VMExit),这种上下文切换,需要耗费一定量的CPU时钟周期,而且很容易引起CPU之间的xcall,性能较差,而Virtio就是因为解决了这个性能问题而被人熟知的。

VirtIO由 Rusty Russell 开发,他当时的目的是支持自己的虚拟化解决方案 lguest。VirtIO 是对准虚拟化 hypervisor 中的一组通用模拟设备IO的抽象。它是一种框架,通过它hypervisor 导出一组通用的模拟设备,并通过一个通用的应用编程接口(API)让它们在虚拟机中变得可用。它构造了一种虚拟化环境所独有的存储设备,因此需要在虚拟机内部安装特定的驱动程序才能正常驱使该设备进行工作。通常我们称虚拟机内部的驱动为前端驱动,称负责实现其功能模拟的程序(KVM平台下即为qemu程序)为后端程序,半模拟技术也常常被叫做前后端技术。采用半摸拟技术后,配合前端驱动,虚拟化设备完全可以采用全新的事件通知和数据传递机制进而大幅提升性能,例如在virtio-blk磁盘中,采用io_event_fd进行前端到后端通知,采用中断注入方式实现后端到前端的通知,并通过IO环(vring)进行数据的共享,IO模型也随之发生变化(如下图所示)。


所以当KVM+Qemu有了Virtio的支持之后,虚拟机中的IO请求就不会在有虚拟机和host之间的切换,而是直接由QEMU中的后端驱动程序直接和host机器中真实的设备驱动通信,完成IO。

下一篇文章,我将讲解VirtIO的技术架构。

展开阅读全文

没有更多推荐了,返回首页