Paper Reading: Xen and the Art of Virtualization
Xen and the Art of Virtualization
Xen 是开源的虚拟化项目,https://xenproject.org/
本文于 2003 年发布,已经 20 年过去了,和目前的虚拟化技术又有什么区别?比如容器化或 Intel VT-X 等等?
直接运行在计算机硬件之上的用以替代操作系统的软件层,虚拟化又分两类、para virtualization 和 hardware virtualization 半虚拟化和完全虚拟化
半虚拟化,超虚拟化,也就是 Xen,虚拟机知道自己是 Xen Hypervisor,也能识别其他运行在相同环境的虚拟机
完全虚拟化,硬件虚拟化,虚拟机会觉得自己直接运行在硬件上
感觉目前的主流还是 KVM (QEMU),内核态基础上做虚拟化,可以重用许多代码,比如内存管理。
事实也正是如此,目前关于虚拟化技术,大部分人都会选择 KVM 而不是 Xen,而且 Xen 能用的 Linux 版本非常古老
似乎 Linux 开发社区比如 Linus 和 Xen 开发人员也有争吵,质疑他们的代码不规范等等。
在 2017 年 Amazon EC2 也去掉了 Xen (安全问题?还是说难以修复)
关于 Xen 为什么发展出现问题,最后比不过 KVM 的相关的历史可以看一看
https://wangxu.me/translation/2009/03/22/xen-to-kernel/index.html
https://fosschef.wordpress.com/2011/06/17/xen-the-road-of-the-life/
ABSTRACT
许多系统已经被设计出来,它们利用虚拟化技术来细分现代计算机的丰富资源。一些系统需要专门的硬件,或者无法支持通用操作系统。一些系统以性能为代价实现了 100% 的二进制兼容性。其他系统则为了速度而牺牲了安全性或功能性。很少有系统提供资源隔离或性能保证;大多数系统只提供尽力而为的资源分配,存在服务拒绝的风险。
This paper presents Xen, an x86 virtual machine monitor which allows multiple commodity operating systems to share conventional hardware in a safe and resource managed fashion, 同时不牺牲性能或功能。这是通过提供一个理想化的虚拟机抽象来实现的,操作系统如 Linux、BSD 和 Windows XP 可以以最小的努力移植到这个抽象上。
我们的设计目标是同时在一台现代服务器上托管多达 100 个虚拟机实例。Xen 采用的虚拟化方法非常高效:我们允许像 Linux 和 Windows XP 这样的操作系统同时托管,性能开销几乎可以忽略不计——最多比非虚拟化情况高出几个百分点。我们在一系列微基准测试和系统级测试中显著优于竞争的商业和免费解决方案。
INTRODUCTION
现代计算机足够强大,可以利用虚拟化技术来呈现许多较小的虚拟机(VM)的假象,每个虚拟机运行一个单独的操作系统实例。
在本文中,我们介绍了 Xen,一种高性能的资源管理虚拟机监视器(VMM),它支持诸如服务器整合[42, 8]、共置托管设施[14]、分布式 Web 服务[43]、安全计算平台[12, 16]和应用程序移动性[26, 37]等应用。
为什么要叫 Monitor 或者 Hypervisor
Xen 应该是直接跑在硬件上,而 VMware 应该是跑在操作系统上
成功地将一台机器分区以支持多个操作系统的并发执行提出了几个挑战。首先,虚拟机必须相互隔离:一个虚拟机的执行不应不利地影响另一个虚拟机的性能。当虚拟机由相互不信任的用户拥有时,这一点尤为重要。其次,有必要支持各种不同的操作系统,以适应流行应用程序的异构性。第三,虚拟化引入的性能开销应该很小。
Xen 使用户能够动态实例化一个操作系统来执行他们想要的任何操作。
有多种方法可以在共享机器上构建托管多个应用程序和服务的系统。也许最简单的方法是部署一个或多个运行标准操作系统(如 Linux 或 Windows)的主机,然后允许用户安装文件并启动进程——应用程序之间的保护由传统的操作系统技术提供。经验表明,由于看似不相关的应用程序之间的复杂配置交互,系统管理可能会迅速成为一项耗时的任务。
this paper focuses on the VMM
更重要的是,这样的系统不能充分支持性能隔离;一个进程的调度优先级、内存需求、网络流量和磁盘访问会影响其他进程的性能。当有足够的资源分配和封闭的用户组(如计算网格或实验性 PlanetLab 平台[33]的情况)时,这可能是可以接受的,但在资源超额预订或用户不合作的情况下则不然。
最重要的问题就是性能隔离
解决这个问题的一种方法是向操作系统添加对性能隔离的支持。这在一定程度上已经通过资源容器[3]、Linux/RK[32]、QLinux[40]和 SILK[4]得到了证明。这种方法的一个困难是确保所有资源使用都归因于正确的进程——例如,考虑由于缓冲区缓存或页面替换算法导致的应用程序之间的复杂交互。这实际上是操作系统内部的“QoS crosstalk”问题[41]。在较低级别进行多路复用可以缓解这个问题,正如 Exokernel[23]和 Nemesis[27]操作系统所展示的那样。任务之间的无意或不希望的交互被最小化。
我们使用相同的基本方法来构建 Xen,它在整个操作系统的粒度上多路复用物理资源,并能够提供它们之间的性能隔离。与进程级多路复用相比,这也允许一系列客户操作系统优雅地共存,而不是强制执行特定的应用程序二进制接口。这种灵活性是有代价的——运行一个完整的操作系统比运行一个进程更重量级,无论是初始化(例如启动或恢复与 fork 和 exec 相比)还是资源消耗。
multiplexes physical resources at the granularity of an entire operating system
操作系统粒度上进行,多路复用物理资源听上去挺有意思
“QoS crosstalk”(服务质量串扰)是指在多任务或多用户环境中,一个任务或用户的操作对其他任务或用户的性能产生不希望的、非预期的影响。这种影响通常是由于资源共享和调度策略导致的,可能会降低整体系统的服务质量(QoS)。
比如缓存污染、资源争用
对于我们最多 100 个托管操作系统实例的目标,我们认为这个代价是值得的;它允许个人用户以资源控制的方式运行未修改的二进制文件或二进制文件集合(例如,一个 Apache 服务器和一个 PostgreSQL 后端)。此外,它提供了极高的灵活性,因为用户可以动态创建其软件所需的精确执行环境。避免了各种服务和应用程序之间不幸的配置交互(例如,每个 Windows 实例维护自己的注册表)。
这里的 binary 是什么,程序进程?
XEN: APPROACH & OVERVIEW
在传统的虚拟机监视器(VMM)中,暴露的虚拟硬件在功能上与底层机器相同。虽然 full virtualization 具有允许托管未修改操作系统的明显优势,但它也有许多缺点。这对于普遍的 IA-32 或 x86 架构尤为明显。
x86 架构的设计从未考虑过全虚拟化支持。某些特权指令必须由 VMM 处理以实现正确的虚拟化,但在权限不足的情况下执行这些指令会静默失败,而不是引发方便的 trap [36]。高效地虚拟化 x86 内**存管理单元(MMU)**也很困难。
VMware 的 ESX Server[10]动态重写托管机器代码的部分内容,以在可能需要 VMM 干预的任何地方插入陷阱。这种转换应用于整个客户操作系统内核(伴随着相关的转换、执行和缓存成本),因为所有非陷阱的特权指令都必须被捕获和处理。ESX Server 实现了系统结构(如页表)的影子版本,并通过捕获每次更新尝试来保持与虚拟表的一致性——这种方法对于更新密集型操作(如创建新的应用程序进程)具有高成本。
ESX Server 全虚拟化 metal Hypervisor
尽管 x86 的复杂性,全虚拟化还有其他反对理由。特别是在某些情况下,托管操作系统既看到真实资源又看到虚拟资源是可取的:提供真实和虚拟时间允许客户操作系统更好地支持时间敏感任务,并正确处理 TCP 超时和 RTT 估计,而暴露真实机器地址允许客户操作系统通过使用 superpages [30]或 page coloring [24]来提高性能。
我们通过提供一个与底层硬件相似但不完全相同的虚拟机抽象来避免全虚拟化的缺点——这种方法被称为半虚拟化[43]。这有望提高性能,尽管它确实需要对客户操作系统进行修改。然而,重要的是要注意,我们不需要更改应用程序二进制接口(ABI),因此不需要对客户应用程序进行修改。
xen 是半虚拟化,支持 x86 和 ARM 等等
应该也支持 HVM 全虚拟化
半虚拟化需要特定内核的操作系统,如基于 Linux paravirt_ops(Linux 内核的一套编译选项)框架的 Linux 内核,而 Windows 操作系统由于其封闭性则不能被 XEN 的半虚拟化所支持,
不需要修改客户应用程序是很重要的
我们将迄今为止的讨论提炼为一组设计原则:
-
支持未修改的应用程序二进制文件是至关重要的,否则用户不会过渡到 Xen。因此,我们必须虚拟化现有标准 ABI 所需的所有架构特性。
-
支持完整的多应用程序操作系统很重要,因为这允许在单个客户操作系统实例中虚拟化复杂的服务器配置。
-
半虚拟化对于在不合作的机器架构(如 x86)上获得高性能和强资源隔离是必要的。
即使在合作的机器架构上,完全隐藏资源虚拟化对客户操作系统的影响也会带来正确性和性能的风险。
ABI 定义应用程序如何在二进制级别与系统交互
请注意,我们半虚拟化的 x86 抽象与最近的 Denali 项目[44]提出的抽象有很大不同。Denali 旨在支持数千个运行网络服务的虚拟机,其中绝大多数是小规模且不受欢迎的。相比之下,Xen 旨在扩展到大约 100 个运行行业标准应用程序和服务的虚拟机。鉴于这些非常不同的目标,将 Denali 的设计选择与我们的原则进行对比是有益的。
首先,Denali 不针对现有的 ABI,因此可以从其虚拟机接口中省略某些架构特性。
其次,Denali 实现不解决在单个客户操作系统内支持应用程序多路复用或多地址空间的问题。类似于 Exokernel 中的 libOS 的方式显式链接到 Ilwaco 客户操作系统实例。 因此,每个虚拟机本质上托管一个单用户单应用程序的无保护“操作系统”。相比之下,在 Xen 中,单个虚拟机托管一个真实的操作系统,该操作系统本身可以安全地多路复用数千个未修改的用户级进程。尽管已经开发了一个原型虚拟 MMU,这可能有助于 Denali 在这一领域[44],但我们不知道任何已发表的技术细节或评估。
第三,在 Denali 架构中,VMM performs all paging to and from disk,这可能与虚拟化层缺乏内存管理支持有关。VMM 中分页与我们性能隔离的目标相反:恶意的虚拟机可以鼓励抖动行为,不公平地剥夺其他虚拟机的 CPU 时间和磁盘带宽。在 Xen 中,我们期望每个客户操作系统使用其自己的保证内存预留和磁盘分配来执行自己的分页(这一想法之前已被 self-paging [20]利用)
最后,Denali 虚拟化了所有机器资源的“命名空间”,认为如果虚拟机无法命名资源,就无法访问其他虚拟机的资源分配(例如,虚拟机对硬件地址一无所知,只知道 Denali 为其创建的虚拟地址)。相比之下,我们认为在虚拟机监视器内的安全访问控制足以确保保护;此外,如前所述,有强有力的正确性和性能论据支持使物理资源直接对客户操作系统可见。
在下一节中,我们将描述 Xen 导出的虚拟机抽象,并讨论客户操作系统必须如何修改以符合这一抽象。请注意,在本文中,我们将术语“客户操作系统 guest operating system” 保留给 Xen 可以托管的操作系统之一,并使用术语“域 domain”来指代在其中执行客户操作系统的运行虚拟机; We call Xen itself the hypervisor since it operates at a higher privilege level than the supervisor code of the guest operating systems that it hosts
The Virtual Machine Interface
表 1 概述了半虚拟化 x86 接口,分为系统三大方面:内存管理、CPU 和设备 I/O。接下来,我们将依次讨论每个机器子系统,并讨论它们在我们半虚拟化架构中的呈现方式。请注意,尽管我们的实现中某些部分(如内存管理)是特定于 x86 的,但许多方面(如我们的虚拟 CPU 和 I/O 设备)可以轻松应用于其他机器架构。此外,x86 在某些方面与其他 RISC 风格处理器存在显著差异,例如,高效虚拟化硬件页表比虚拟化软件管理的 TLB 更为困难。
Memory management
Virtualizing memory 无疑是半虚拟化架构中最困难的部分,无论是从虚拟机监视器所需的机制还是从移植每个客户操作系统所需的修改来看。如果架构提供软件管理的 TLB,这项任务会更容易,因为这些 TLB 可以以简单的方式高效虚拟化[13]。带标签的 TLB 是大多数服务器级 RISC 架构(包括 Alpha、MIPS 和 SPARC)支持的另一个有用功能。将地址空间标识符标签与每个 TLB 条目相关联,允许虚拟机监视器和每个客户操作系统在单独的地址空间中高效共存,因为不需要在转移执行时刷新整个 TLB。
不幸的是,x86 没有软件管理的 TLB;相反,TLB 未命中由处理器通过硬件遍历页表结构自动处理。因此,为了实现最佳性能,当前地址空间的所有有效页翻译应存在于硬件可访问的页表中。此外,由于 TLB 未带标签,地址空间切换通常需要完全刷新 TLB。鉴于这些限制,我们做出了两个决定:(i) 客户操作系统负责分配和管理硬件页表,Xen 仅在确保安全和隔离的情况下进行最小程度的参与;(ii) Xen 存在于每个地址空间的顶部 64MB 区域,从而在进入和离开虚拟机监视器时避免 TLB 刷新。
每当客户操作系统需要一个新的页表时(例如,因为正在创建一个新进程),它会从自己的内存预留中分配并初始化一个页面,并将其注册到 Xen。此时,操作系统必须放弃对页表内存的直接写权限:所有后续更新必须由 Xen 验证。这限制了更新的方式,包括只允许操作系统映射其拥有的页面,并禁止对页表的可写映射。客户操作系统可以批量更新请求,以分摊进入虚拟机监视器的开销。每个地址空间的顶部 64MB 区域,保留给 Xen,不可由客户操作系统访问或重新映射。然而,这个地址区域不被任何常见的 x86 ABI 使用,因此这个限制不会破坏应用程序兼容性。
分段以类似的方式虚拟化,通过验证对硬件段描述符表的更新。x86 段描述符的唯一限制是:(i) 它们必须比 Xen 具有更低的特权,(ii) 它们不得允许访问 Xen 保留的地址空间部分。
CPU
虚拟化 CPU 对客户操作系统有几个影响。主要的是,在操作系统之下插入一个虚拟机监视器违反了操作系统是系统中最特权实体的通常假设。为了保护虚拟机监视器免受操作系统错误行为的影响(以及域之间的相互保护),客户操作系统必须修改为在较低的特权级别上运行。
许多处理器架构只提供两个特权级别。
内核模式,用户模式
和 x86 里的 ring0-3 有什么区别?
在 x86 上可以高效地虚拟化特权级别,因为它在硬件上支持四个不同的特权级别。x86 特权级别通常被称为环,编号从零(最高特权)到三(最低特权)。 操作系统代码通常在环 0 中执行,因为没有其他环可以执行特权指令,而环 3 通常用于应用程序代码。据我们所知,自 OS/2 以来,环 1 和环 2 没有被任何知名的 x86 操作系统使用过。任何遵循这种常见安排的操作系统都可以通过修改其在环 1 中执行来移植到 Xen。这可以防止客户操作系统直接执行特权指令,同时它仍然安全地与在环 3 中运行的应用程序隔离。
x86 可以这么干,那其他架构呢,ARM 也有 Exception Level 0-3
通常只有两种类型的异常频繁发生,足以影响系统性能:系统调用(通常通过软件异常实现)和页面错误。我们通过允许每个客户操作系统注册一个“快速”异常处理程序来提高系统调用的性能,该处理程序由处理器直接访问,无需通过环 0 间接访问;在将此处理程序安装到硬件异常表之前进行验证。不幸的是,无法将相同的技术应用于页面错误处理程序,因为只有环 0 中的代码可以从寄存器 CR2 读取故障地址;因此,页面错误必须始终通过 Xen 传递,以便可以保存此寄存器值以在环 1 中访问。
page fault 确实是个问题
通过在向 Xen 呈现异常处理程序时验证它们来确保安全性。唯一需要的检查是处理程序的代码段不指定在环 0 中执行。由于没有客户操作系统可以创建这样的段,因此将指定的段选择器与 Xen 保留的一小部分静态值进行比较就足够了。除此之外,任何其他处理程序问题都在异常传播期间修复——例如,如果处理程序的代码段不存在或处理程序未分页到内存中,则在 Xen 执行返回处理程序的 iret 指令时将发生适当的故障。Xen 通过检查故障程序计数器值来检测这些“双重故障”:如果地址位于异常虚拟化代码中,则终止有问题的客户操作系统。
由 Xen 来验证,比如检查代码段,检查特权级别、静态值
异常传播修复,是什么意思?
请注意,即使对于直接系统调用处理程序,这种“懒惰”检查也是安全的:当 CPU 尝试直接跳转到客户操作系统处理程序时,将发生访问故障。在这种情况下,故障地址将在 Xen 之外(因为 Xen 永远不会执行客户操作系统的系统调用),因此故障以正常方式虚拟化。如果故障的传播导致进一步的 “double fault”,则如上所述终止客户操作系统。
Device I/OS
与通常在完全虚拟化环境中模拟现有硬件设备不同,Xen 暴露了一组干净且简单的设备抽象。这使我们能够设计一个既高效又满足我们对保护和隔离要求的接口。为此,I/O 数据通过 Xen 在每个域之间传输,使用共享内存、异步缓冲区描述符环。这些环提供了一种高性能的通信机制,用于在系统中垂直传递缓冲区信息,同时允许 Xen 高效地执行验证检查(例如,检查缓冲区是否包含在域的内存预留中)。
类似于硬件中断,Xen 支持一种轻量级的事件传递机制,用于向域发送异步通知。这些通知通过更新待处理事件类型的位图来实现,并且可以选择性地调用由客户操作系统指定的事件处理程序。这些回调可以根据客户操作系统的判断“暂停”——例如,为了避免频繁唤醒通知带来的额外开销。
domain 到底是一个虚拟机实例还是什么
The Cost of Porting an OS to Xen
XP 不好移植
这样的移植感觉很费力,除非是开源的 OS,闭源的感觉难以操作
Control and Management
Domain 0 跑了一个 guestOS 负责 control software ,XenoLinux 应该也是 Xen 的
其他 guestOs 可以是 xenoLinux 也可以是 xenoBSD 等等
separate policy from mechanism wherever possible
尽管虚拟机监视器必须在数据路径方面(例如,在域之间调度 CPU,在传输之前过滤网络包,或在读取数据块时执行访问控制)进行参与,但没有必要让它参与或甚至了解更高层次的问题,例如如何共享 CPU,或每个域可以传输哪种类型的包。
由此产生的架构是,虚拟机监视器本身只提供基本的控制操作。这些操作通过一个可以从授权域访问的接口导出;潜在复杂的策略决策,如准入控制,最好由在 running over a guest OS 上运行的管理软件执行,而不是在特权虚拟机监视器代码中执行。
这个思路感觉和 kvm / hyper-v 完全虚拟化区别的还是很大的
DETAILED DESIGN
Control Transfer: Hypercalls and Events
Xen 与上层域之间的控制交互存在两种机制:域可以使用 Hypercalls 向 Xen 进行同步调用,而 Xen 使用异步事件机制向域传递通知。
hypercall 接口允许域执行 synchronous software trap 进入虚拟机监视器以执行特权操作,类似于传统操作系统中使用系统调用的方式。超调用的一个示例用途是请求一组页表更新,其中 Xen 验证并应用更新列表,并在完成后将控制权返回给调用域。
Xen 与域之间的通信通过异步事件机制提供,该机制取代了设备中断的常规传递机制,并允许对重要事件(如域终止请求)进行轻量级通知。类似于传统的 Unix 信号,只有少数事件,每个事件用于标记特定类型的发生。例如,事件用于指示已通过网络接收到新数据,或虚拟磁盘请求已完成。
待处理事件 Pending events 存储在每个域的位掩码中,Xen 在调用由客户操作系统指定的事件回调处理程序之前更新该位掩码。回调处理程序负责重置待处理事件集,并以适当的方式响应通知。域可以通过设置 Xen 可读的软件标志显式推迟事件处理:这类似于在真实处理器上禁用中断。
Data Transfer: I/O Rings
The presence of a hypervisor means there is an additional protection domain between guest OSes and I/O devices, so it is crucial that a data transfer mechanism be provided that allows data to move vertically through the system with as little overhead as possible
resource management
event notification
为了资源责任,我们试图在从设备接收到中断时最小化将数据多路分解到特定域所需的工作——管理缓冲区的开销稍后进行,计算可能归因于适当的域。 类似地,尽可能由相关域提供用于设备 I/O 的内存,以防止共享缓冲池中固有的串扰;在数据传输期间,通过在 Xen 中固定底层页帧来保护 I/O 缓冲区。
图 2 展示了我们 I/O 描述符环的结构。环是由域分配的描述符的循环队列,但可以从 Xen 内部访问。描述符不直接包含 I/O 数据;相反,I/O 数据缓冲区由客户操作系统带外分配,并通过 I/O 描述符间接引用。对每个环的访问基于两对生产者-消费者指针:域在环上放置请求,推进请求生产者指针,Xen 移除这些请求进行处理,推进相关的请求消费者指针。响应以类似的方式放回环中,只是 Xen 作为生产者,客户操作系统作为消费者。没有要求按顺序处理请求:客户操作系统为每个请求关联一个唯一标识符,该标识符在相关响应中重现。这允许 Xen 由于调度或优先级考虑而明确地重新排序 I/O 操作。
这里的 IO ring 和 NIC 的是不是很类似
这种结构足够通用,可以支持多种不同的设备范式。例如,一组“请求”可以为网络数据包接收提供缓冲区;随后的“响应”然后通知这些缓冲区中数据包的到达。在处理磁盘请求时,重新排序是有用的,因为它允许在 Xen 中调度它们以提高效率,并且使用带外缓冲区的描述符使得实现零拷贝传输变得容易。
Xen 实现了零拷贝吗
https://wiki.xenproject.org/wiki/Xen_4.3_Block_Protocol_Scalability
blkback/blkfront
我们将请求或响应的生产与另一方的通知解耦:在请求的情况下,域可以在调用超调用以提醒 Xen 之前将多个条目排队;在响应的情况下,域可以通过指定响应阈值数量来推迟通知事件的传递。这允许每个域根据延迟和吞吐量要求进行权衡,类似于 ArseNIC 千兆以太网接口中的流量感知中断调度
Subsystem Virtualization
CPU scheduling
Xen 目前根据 Borrowed Virtual Time(BVT)调度算法[11]调度域,因为它既节省工作量,又有一个特殊的机制用于低延迟唤醒(或调度)域,当它接收到事件时。快速调度对于最小化虚拟化对设计为及时运行的操作系统子系统的影响尤为重要;例如,TCP 依赖于及时交付确认以正确估计网络往返时间。BVT 通过使用虚拟时间扭曲机制提供低延迟调度,该机制暂时违反“理想”的公平共享,以支持最近唤醒的域。然而,其他调度算法可以简单地在我们通用的调度器抽象上实现。每个域的调度参数可以通过在 Domain0 中运行的管理软件进行调整。
Time and timers
Xen 为客户操作系统提供了真实时间、虚拟时间和挂钟时间的概念。
配合 BVT 算法?
Virtual address translation
Xen 试图以尽可能小的开销虚拟化内存访问。
由于 x86 架构使用硬件页表,这一目标变得更加困难。VMware 的方法是为每个客户操作系统提供一个虚拟页表,该页表对内存管理单元(MMU)不可见 然后,虚拟机监视器负责捕获对虚拟页表的访问,验证更新,并将更改在虚拟页表和 MMU 可见的“影子”页表之间来回传播。这大大增加了某些客户操作系统操作的成本,例如创建新的虚拟地址空间,并需要显式传播硬件更新到“访问”和“脏”位
尽管完全虚拟化迫使使用影子页表,以提供连续物理内存的假象,但 Xen 并不受此限制。事实上,Xen 只需要在页表更新时介入,以防止客户操作系统进行不可接受的更改。因此,我们避免了与使用影子页表相关的开销和额外复杂性——Xen 的方法是直接向 MMU 注册客户操作系统页表,并限制客户操作系统对页表的只读访问。页表更新通过超调用传递给 Xen;为了确保安全,请求在应用之前进行验证。
Hyper-V 应该都是用的 shadow page table 或者能管理 TLB
KVM 应该用了硬件 EPT,这个之前见过
Xen 通过半虚拟化技术进行虚拟内存转换,要求客户操作系统进行修改以适应虚拟化环境。以下是 Xen 进行虚拟内存转换的主要步骤和机制:
页表注册:Xen 直接向内存管理单元(MMU)注册客户操作系统的页表,并限制客户操作系统对页表的只读访问。
页表更新:页表更新通过超调用传递给 Xen,并在应用之前进行验证。
类型系统:Xen 为每个机器页帧关联一个类型和引用计数。类型包括页目录(PD)、页表(PT)、本地描述符表(LDT)、全局描述符表(GDT)或可写(RW)。
引用计数:只有在引用计数为零时,帧才能安全地重新分配任务。这确保了内存管理的安全性和隔离性。
验证机制:客户操作系统指示何时为页表使用分配帧,Xen 对帧中的每个条目进行一次性验证。验证通过后,帧的类型固定为 PD 或 PT,直到客户操作系统发出取消固定请求。
固定机制:固定机制在更改页表基指针时特别有用,因为它消除了在每个上下文切换时验证新页表的需要。
批量更新:为了最小化所需的超调用数量,客户操作系统可以在应用整个批次之前本地排队更新,并通过单个超调用应用。这在创建新地址空间时特别有益。
更新提交:更新必须在 TLB 刷新之前提交,以保证正确性。客户操作系统通常在首次使用新映射之前执行 TLB 刷新,确保任何缓存的翻译无效。
故障处理:如果客户操作系统在确定 TLB 中不存在陈旧条目时省略刷新,首次尝试使用新映射可能会导致页面不存在故障。客户操作系统故障处理程序必须检查是否有未完成的更新。
重试机制:如果找到未完成的更新,则刷新它们并重试故障指令,确保内存映射的正确性。
Physical memory
每个域的初始内存分配或预留是在其创建时指定的,因此,内存在域之间静态分区,提供强隔离。还可以指定最大允许预留:如果域内的内存压力增加,它可能会尝试从 Xen 中获取额外的内存页,直到此预留限制。相反,如果域希望节省资源,可能为了避免产生不必要的成本,它可以通过将内存页释放回 Xen 来减少其内存预留。
XenoLinux implements a balloon driver, 通过在 Xen 和 XenoLinux 的页面分配器之间来回传递内存页来调整域的内存使用。尽管我们可以直接修改 Linux 的内存管理例程,但气球驱动程序通过使用现有的操作系统功能进行调整,从而简化了 Linux 移植工作。然而,半虚拟化可以用来扩展气球驱动程序的功能;例如,客户操作系统中的内存不足处理机制可以修改为通过从 Xen 请求更多内存来自动缓解内存压力。
大多数操作系统假设内存最多由几个大的连续区域组成。因为 Xen 不保证分配连续的内存区域,客户操作系统通常会为自己创造连续物理内存的假象,
Xen 不保证分配连续的内存区域
Network
Domain0 负责插入和删除规则。
为了发送数据包,客户操作系统只需将缓冲区描述符排队到发送环上。Xen 复制描述符,并确保安全,然后复制数据包头并执行任何匹配的过滤规则。数据包负载不会被复制,因为我们使用 scatter-gather DMA;但是请注意,相关的页帧必须固定,直到传输完成。为了确保公平性,Xen 实现了一个简单的轮询数据包调度器。
fairness -> round-robin
有没有性能更好的
Disk
只有 Domain0 可以直接无限制地访问物理磁盘(IDE 和 SCSI)。所有其他域通过虚拟块设备(VBD)的抽象来访问持久存储,这些虚拟块设备由在 Domain0 内运行的管理软件创建和配置。允许 Domain0 管理 VBD 使得 Xen 的机制非常简单,避免了更复杂的解决方案,例如 Exokernel 使用的 UDFs [23]。
一个 VBD 包含一个范围列表,以及相关的所有权和访问控制信息,并通过 I/O 环机制进行访问。
ExoKernel 支持 UDF?是怎么做到的,用户可以自定义访问 IO 吗
VBD 是虚拟块设备 virtual block devices
VBD 是一种抽象层,用于将物理磁盘资源虚拟化为多个虚拟磁盘设备,供不同的虚拟机(域)使用。
Xen 以简单的轮询方式处理来自竞争域的批量请求;这些请求随后被传递给 evator scheduler 调度程序,然后再到达磁盘硬件。域可以显式传递重新 reorder barriers, 以防止在需要维护更高级别语义时进行重新排序(例如,在使用预写日志时)。低级调度为我们提供了良好的吞吐量,而请求的批处理提供了相当公平的访问。未来的工作将研究提供更可预测的隔离和差异化服务,可能使用现有的技术和调度程序
磁盘调度应该也是个有意思的方向
Building a New Domain
为新域构建初始客户操作系统结构的任务主要委托给 Domain0,Domain0 使用其特权控制接口(第 2.3 节)访问新域的内存并通知 Xen 初始寄存器状态。
Evaluation
性能评估应该是 Xen 的重头戏
我们首先将 Xen 与多种替代虚拟化技术进行基准测试,然后比较在单个原生操作系统上同时执行多个应用程序的总系统吞吐量与在每个虚拟机中运行每个应用程序的总系统吞吐量。
评估了 Xen 在客户操作系统之间提供的性能隔离
XenoLinux 移植(基于 Linux 2.4.21),因为这是我们最成熟的客户操作系统。我们预计 Windows XP 和 NetBSD 移植的相对开销会相似,但尚未进行全面评估。
机器中的 Xeon 处理器支持 SMT(“超线程”),但由于当前内核都没有 SMT 感知的调度程序,因此禁用了此功能。我们确保所有客户操作系统及其虚拟机管理程序可用的总内存量等于原生 Linux 可用的总内存量。
Relative Performance
下一组条形图显示了在本地 ext3 文件系统上使用 gcc 2.96 构建 Linux 2.4.21 内核默认配置所花费的总时间。原生 Linux 花费了大约 7%的 CPU 时间在操作系统中,主要执行文件 I/O、调度和内存管理。在虚拟机管理程序的情况下,这种“系统时间”在不同程度上被扩展:Xen 仅增加了 3%的开销,而其他虚拟机管理程序则经历了更显著的减速。
我们使用 PostgreSQL 7.1.3 数据库进行了两个实验,通过默认配置的 Open Source Database Benchmark 套件(OSDB)进行测试。我
对比了很多 benchmark
选了几个有意思的,实际上涉及到 DB 操作或者磁盘操作,性能会有一些下降
但其他情况性能几乎是原生一致的
性能这么好的原因是什么,xenoLinux 和 半虚拟化吗,还是 IO ring、还是内存管理
调度算法感觉都是为了公平,但为什么会这么好
奇怪的是横坐标是 Relative Score
Operating System Benchmarks
为了更精确地测量 Xen 和其他虚拟机管理程序(VMM)中的开销区域,我们进行了许多针对特定子系统的小型实验
在进程微基准测试(表 3)中,Xen 的 fork、exec 和 sh 性能比原生 Linux 慢。这是预期的,因为这些操作需要大量的页表更新,这些更新必须全部由 Xen 验证。然而,半虚拟化方法允许 XenoLinux 批量更新请求。创建新的页表是一个理想的情况:因为没有理由更早地提交待处理的更新,XenoLinux 可以在每次超调用中分摊 2048 次更新(其批处理缓冲区的最大大小)。因此,每次更新超调用构造 8MB 的地址空间。
表 5 中显示的 mmap 延迟和页面故障延迟结果很有趣,因为它们每页需要两次进入 Xen 的转换:一次是处理硬件故障并将详细信息传递给客户操作系统,另一次是代表客户操作系统安装更新的页表条目。尽管如此,开销相对较小。
开销几乎和原生是没区别的
就是 fork 之类的要慢一些,需要通过 xen 来验证页表创建
上下文切换、内存管理等等。
Network performance
为了评估虚拟化网络的开销,我们检查了通过千兆以太网局域网的 TCP 性能。
为什么 TCP MTU 500 反而性能要低一些?
使用 500 字节的 MTU 时,每包开销占主导地位。发送防火墙和接收多路复用的额外复杂性对吞吐量产生了不利影响,但仅降低了 14%。
Concurrent Virtual Machines
在图 5 中,我们展示了 Xen 在运行 1、2、4 和 8 个 OSDB-IR 和 OSDB-OLTP 实例时实现的总吞吐量。当添加第二个域时,第二个 CPU 的充分利用几乎使总吞吐量翻倍。进一步增加域的数量会导致总吞吐量有所下降,这可以归因于增加的上下文切换和磁盘头移动。在单个 Linux 操作系统上运行多个 PostgreSQL 实例的总分数比使用 Xen 的等效分数低 25-35%。原因尚未完全理解,但似乎 PostgreSQL 存在 SMP 可扩展性问题,并且未能充分利用 Linux 的块缓存。
图 5 还展示了 8 个域之间的性能差异化。Xen 的调度器配置为给每个域一个介于 1 和 8 之间的整数权重。每个域的吞吐量分数反映在条形图的不同分段中。在 IR 基准测试中,权重对吞吐量有精确的影响,每个分段都在其预期大小的 4%以内。然而,在 OLTP 情况下,分配更多资源的域未能实现成比例的高分数:高水平的同步磁盘活动突显了我们当前磁盘调度算法的弱点,导致它们表现不佳
磁盘调度是个问题,前文也提到
Performance Isolation
第四个域同时运行了一个“fork 炸弹”和一个虚拟内存密集型应用程序,该应用程序尝试分配和接触 3GB 的虚拟内存,并在失败时释放每个页面然后重新启动。
我们发现,OSDB-IR 和 SPEC WEB99 的结果仅受到运行破坏性过程的两个域的行为的轻微影响——分别比之前报告的结果低 4%和 2%。我们将此归因于额外的上下文切换和缓存效应的开销。考虑到我们当前相对简单的磁盘调度算法,我们认为这是有些幸运的,但在这种情况下,它似乎为基准测试提供了足够的隔离,使其能够从其他域的页面交换和磁盘密集型活动中取得良好的进展。VMware Workstation 实现了类似的隔离水平,但绝对性能水平较低。
论文希望实现的是 P. Shenoy and H. Vin. Cello: A Disk Scheduling Framework for Next-generation Operating Systems. In Proceedings of ACM SIGMETRICS’98, the International Conference on Measurement and Modeling of Computer Systems, pages 44–55, June 1998.
这里的性能隔离可能不如 KVM
Scalability
在本节中,我们考察了 Xen 扩展到 100 个域的能力。我们讨论了运行许多客户操作系统实例及其相关应用程序的内存需求,并测量了其执行的 CPU 性能开销。
Related Work
如我们的评估所示,选择完全虚拟化虽然能够更容易地支持现成的操作系统,但对性能有不利影响。
目前,我们知道另外两个采用半虚拟化方法的系统:IBM 目前支持其 zSeries 大型机上的 Linux 半虚拟化版本,允许大量 Linux 实例同时运行。Denali [44],前面讨论过,是一个当代的隔离内核,试图提供一个能够托管大量虚拟化操作系统实例的系统。
我们与操作系统的可扩展性和主动网络社区有一些动机。然而,当在 Xen 上运行时,不需要检查“安全”代码或保证终止——在任何一种情况下,唯一受影响的人是相关客户。因此,Xen 提供了一个更通用的解决方案:托管代码不需要由受信任的编译器进行数字签名(如 SPIN [5]),不需要附带安全证明(如 PCC [31]),不需要用特定语言编写(如 SafetyNet [22] 或任何基于 Java 的系统),也不需要依赖特定中间件(如移动代理系统)。当然,这些其他技术可以在运行在 Xen 上的客户操作系统内继续使用。这对于具有更多临时任务的工作负载可能特别有用,这些任务不会提供启动新域的机会来分摊成本。
Conclusion
VMWare 成立于 1998
Xen 很多想法都是半虚拟化,paravirtualization 而不是完全虚拟化,使用 Domain0 来管理客制化的 OS,需要实现 OS
随着后面 Intel VT-X/ AMD SVM 的出现,KVM 的性能也可以接近原生,Xen 也开始支持 HVM,也加入了 Linux Foundation
Xen 限制还是挺大的,要实现 OS,兼容性没那么好(直到 2012 才实现了 ARM),应该有不少文章对比 KVM 和 Xen 的性能
可能这也是 Xen 现在发展完全不如 KVM 的根源所在吧,尽管 Xen 性能略优,但兼容性和使用门槛才是商业化的敲门砖,不过 Xen 后面被 Citrix 收购了可能商业化会好很多,也推出了全虚拟化 HVM 版本(貌似是 Windows)
https://ieeexplore.ieee.org/abstract/document/6714189
S. G. Soriga and M. Barbulescu, “A comparison of the performance and scalability of Xen and KVM hypervisors,” 2013 RoEduNet International Conference 12th Edition: Networking in Education and Research, Iasi, Romania, 2013, pp. 1-6, doi: 10.1109/RoEduNet.2013.6714189.