坑边闲话:虚拟机能利用通用计算的能力模拟出很多实机本身并不具备的硬件,比如通过软件实现一个万兆网络等。但是对虚机而言,某些场景不仅仅需要设备的完备,更需要硬件的高性能。在这种情况下,如果不能提供足够的的硬件性能损耗,那么用户可能不太乐意买单。在这种场景下,逐渐衍生出了硬件直通技术 Hardware Passthrough 和 SR-IOV 技术。

软件版本

本教程适用于 ESXi 7.0 和 8.0 版本。

1. 故事还得从图灵机开始说起·

阿兰·图灵在提出图灵机计算机模型时,解决了很多重要的问题。其中包括指明哪些问题是可计算的,哪些是计算机无法解决的。同时,图灵的《论可计算数》这篇文章还产生了很多推论,那就是有多条 Tape 的图灵机在计算能力上与单 tape 图灵机是一致的。这也就是说,哪怕你给最朴素的图灵机多加几个纸带,也顶多是提高计算效率,并不能让改进版机器解决先前机器所不能解决的问题。(这一段看不懂不要紧!)

上述一段话虽然太理论化,但是也是十分重要的。一般与学生打交道时,我会问他们一个问题:显卡是不是一个 Computer?同学们大致有以下几种结论。

  1. 显卡是 PCIe 设备,即 Peripheral 设备,外设。外设本质上不属于计算机,而是一个辅助计算的东西,相当于图灵机的额外的“纸带”,只加速计算。
  2. 显卡必然是一个独立的计算机,尽管它不能独立地工作,但是它有自己的指令集,能处理很多独立的事务。

我认为,上述两种观点都是正确的,但是也都不完全正确。从图灵机模型上看,显卡有指令存储单元,也有自己的大规模 ALU,所以它“很”是个图灵机。但是反着来看,显卡并不能独立工作。所以这个问题只是个思考题,并没有答案。

啰啰嗦嗦说了这么多,我个人还是倾向于把显卡当作一个计算机来看待的。在这种观点下,你的 PC 其实是多个计算机交互的总体。CPU 加内存是计算机,磁盘控制器是计算机,网络控制器也是计算机。他们在加电之后,就在统一指挥官 CPU 的统领之下,开始了密切合作,为你勤恳工作。

根据图灵理论,任意复杂的可被计算的功能都可以通过简单的通用计算机模拟出来。(如果不考虑效率。)而这个理论也是软件模拟的核心原理。如今的 Qemu、bochs 等模拟器也是基于此原理。

但是,如果所有的东西都让软件模拟,那么效率过低的问题就变得很突出。比如我们在一个性能较弱的 PC 上运行虚拟化程序,模拟了一个网卡。考虑到这台计算机本身性能就不太好,所以这个模拟出来的网卡的吞吐性能可能不高,无法满足虚拟机用户的需求。而很多虚拟机平台严重依赖软件模拟硬件,这就导致 Hypervisor 的 CPU 主频严重浪费在了模拟硬件上,并没有发挥出很高的计算效力。这该如何是好呢?

2. 配有良好驱动的硬件就是文件·

很多朋友应该听过一句话:在 Linux 世界里,一切皆文件。这句话的意思是说,一个硬件只要搭配好合适的驱动,那么就能像一个文件那样被读取、写入。反过来说,如果一个硬件并没有加载好对应的驱动,那么就不能被调用,换言之就是不能被内核读写。

上述是一个很笼统的描述,有很多细节问题还需要我们考虑。首先,Linux 内核要调用显卡、网卡,本质上就是调用了 Linux 目录下的某个文件。读文件、写文件就等效于调用显卡、网卡。那么问题来了,该怎么读写这种代表硬件的文件呢?

3. 硬件直通·

4. SR-IOV·

由于硬件直通在多客户机的管理情况下非常麻烦,毕竟硬件直通就意味着该设备被某客户机独占,其他客户机就享受不到这种资源了。然而,在大部分情况下,直通了硬件的客户机并不时刻让该硬件满载,这也造成了硬件资源的浪费。

软硬件发展这么多年,一个很明显的趋势就是:隔离、高效。同一个系统之上,进程之间要隔离,彼此的内存空间不能互相访问;地址空间的内核区和用户区要隔离,防止安全隐患出现。至于高效就更加能顾名思义了。我们希望硬件能时刻满负荷运行,毕竟计算力是一种生产力,老板们都不想让工厂里的工人闲着。

SR-IOV 就是在上述需求下产生的。

把万兆网卡直通给某个虚拟机 A,它可能偶尔才用一下这个万兆网卡。如果有办法在这个万兆网卡内加一个交换设备,然后产生许多个与该万兆网卡类似的虚设备,所有的需设备共享万兆带宽。通过这种方式产生的若干个轻量级虚设备可以直通给若干虚拟机,当这些轻量级虚设备产生活动时,由真实的万兆网卡集中处理。任意一个虚设备的性能上限与物理设备的上限基本一致。这就很有灵活性了!

但是很遗憾,尽管这种理念很先进很好,但是支持的硬件并不是很多。只有少部分高级的、昂贵的专业设备才支持。

5. USB 设备直通·

To be continued.