本文首发于我的公众号 Linux云计算网路(id: cloud_dev),号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,第一时间掌握技术干货!

I/O 虚拟化在虚拟化技术中算是比较复杂,也是最重要的一部分。从整体上看,I/O 虚拟化也包括基于软体的虚拟化和硬体辅助的虚拟化,软体虚拟化部分又可以分为全虚拟化和半虚拟化,如果根据设备类型再细分的话,又可以分为字元设备 I/O 虚拟化(键盘、滑鼠、显示器)、块设备 I/O 虚拟化(磁碟、光碟)和网路设备 I/O 虚拟化(网卡)等。

我们先看下在没有虚拟机存在的情况下,I/O 设备请求是怎样的。某个应用或进程发出 I/O 请求,通过系统调用等方式进入内核,调用相应的驱动程序,请求到具体的 I/O 设备,然后再将结果返回到调用者进行回显。

那么存在虚拟机的情况下,又是怎样的呢。按理说,虚拟机是宿主机上的一个进程,应该可以以类似的 I/O 请求方式访问到宿主机上的 I/O 设备,但别忘了,虚拟机处在非 Root 的虚拟化模式下,请求无法直接下发到宿主机,必须借助于 VMM 来截获并模拟虚拟机的 I/O 请求,至于怎么截获并模拟,每一种 VMM 的实现方案都不一样,像 qemu-kvm ,截获操作是由内核态的 kvm 来完成,模拟操作是由用户态的 qemu 来完成的,这也是 kvm 不同于其他 VMM 实现方案的地方。kvm 这样做也是为了提升性能和保持内核的纯净性,关于这块的知识不清楚的可以查阅前文。

从层次上看,虚拟机发出 I/O 请求到完成相应的 I/O 操作,中间要经过虚拟机的设备驱动,到 VMM 的设备模型,再到宿主机的设备驱动,最终才到真正的 I/O 设备。

那什么是设备模型,设备模型就是 VMM 中进行设备模拟,并处理所有设备请求和响应的逻辑模块,对于 qemu-kvm,qemu 其实就可以看做是一个设备模型。

上图显示的就是设备模型的逻辑层次关系,对于不同构造的虚拟机,其逻辑层次是类似的:VMM 截获虚拟机的 I/O 操作,将这些操作传递给设备模型进行处理,设备模型运行在一个特定的环境下,这可以是宿主机,可以是 VMM 本身,也可以是另一个虚拟机。

下图显示的就是在宿主机中设备模型的实现,也就是 qemu-kvm 的实现方案,在这个例子中,VMM 主要部分实现为内核模块,设备模型实现为一个用户态进程,当虚拟机发生 I/O 之后,VMM 作为内核模块将其截获后,会通过内核态-用户态介面传递给用户态的设备模型处理,设备模型运行与宿主机操作系统之上,可以使用相应的系统调用和所有运行时库,宿主机操作系统就是设备模型的运行环境。

所以,设备模型在这里起著一个桥梁的作用,由虚拟机设备驱动发出的 I/O 请求先通过设备模型转化为物理 I/O 设备的请求,再通过调用物理设备驱动来完成相应的 I/O 操作。反过来,设备驱动将 I/O 操作结果通过设备模型,返回给虚拟机的虚拟设备驱动程序。

上面说的这种方式是纯软体模拟的,或者说得再专业一点就是全虚拟化,全虚拟化就是 VMM 完全虚拟出一套宿主机的设备模型,宿主机有什么就虚拟出什么,这样,虚拟机发出的任何 I/O 请求都是无感知的,也是说虚拟机认为自己在「直接」使用物理的 I/O 设备,其实不是,全是虚拟出来的。

有了全虚拟化,自然就有半虚拟化,半虚拟化的提出就是解决全虚拟化的性能问题的。通过上面的分析,不难看出,这种截获再模拟的方式导致一次 I/O 请求要经过多次的内核态和用户态的切换,性能肯定不理想。半虚拟化就是尽量避免这种情况发生。

半虚拟化中,虚拟机能够感知到自己是处于虚拟化状态,虚拟机和宿主机之间通过某种机制来达成这种感知,也就是两者之间需要建立一套通信介面,虚拟机的 I/O 请求走这套介面,而不是走截获模拟那种方式,这样就可以提升性能。这套介面一个比较好的实现就是 virtio,Linux 2.6.30 版本之后就被集成到了 Linux 内核模块中。

半虚拟化虽然提升了性能,但是还是基于软体模拟的方式,性能上还是无法与直接访问物理 I/O 设备相抗衡,那能不能做到呢,答案是一定的,那就是从硬体上去入手了。

以 Intel VT-d 为首的技术就是硬体辅助的 I/O 虚拟化技术,但是业界一般不是直接使用硬体,而是配合相应的软体技术来完成,比较常用的两门技术是 PCI Pass-Through 和 SR-IOV。

本文仅是简单总结下 I/O 虚拟化的方式,分类,以及存在的技术问题。后面会针对具体的类别或问题进行展开。


公众号后台回复「加群」,带你进入高手如云交流群

我的公众号 Linux云计算网路(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网路、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。


推荐阅读:
相关文章