LWN:扩展KVM社区!

关注了就能看到更多这么棒的文章哦~

Scaling the KVM community

November 15, 2022
This article was contributed by Paolo Bonzini
KVM Forum
DeepL assisted translation
https://lwn.net/Articles/914638/

Linus Torvalds 的可扩展性(scalability,意为工作量上来之后他会成为瓶颈)是 Linux 早期的一个反复出现的话题。而近年来维护者的斗争则是开源社区内公认存在的问题了。因此,Sean Christopherson 理所应当地在欧洲开源峰会(和 KVM 论坛)上发表了题为 "扩展 KVM 及其社区 "的演讲。这次演讲主要集中在 KVM 的 x86 架构(这是最大且最成熟的 KVM 架构了),Christopherson 作为共同维护者。但这并不是一个技术讲座,其中的大部分内容都适用于其他 KVM 架构,甚至包括 Linux 中其他子系统,这样他们就可以避免犯同样类型的错误。

The problem

KVM hypervisor 并不是个小项目:它涵盖了 6 个架构,每个架构通常都支持虚拟化中的各种 "flavor"。它包括了 150,000 行代码,加上 90,000 行 test 代码,其中包括 kernel self tests] 以及 kvm-unit-test 项目。每年有超过 150 个贡献者贡献了超过 1000 个提交。这些数字预计会继续增长,Christopherson 指出了需要扩展三个领域才能适应 KVM 的增长。

  • 开发:KVM 需要支持新出现的架构、现有架构的新功能、以及新的虚拟化使用场景。

  • 维护:更广泛的架构、功能和使用场景意味着有更多的 patch 需要 review,更多的代码需要维护。

  • 验证:越来越多的代码意味着会有更多的东西会被破坏。

值得注意的是,扩大开发和维护规模并不一定需要更多的开发人员和更多的维护人员。如果现有的开发者和维护者能够更有效率,比如说引入更少的 bug,也可以有效支持更大规模。事实上,增加更多的开发者和维护者而不改善验证工作的话,反而会使开发和维护工作变得更慢、更昂贵。值得注意的是,每当 Christopherson 在整个演讲中提到维护者时,他也把那些在 MAINTAINERS 文件中被列为 "reviewers" 以及那些定期分流(triaging)和 fixing bug 的人算在了这个群体里。

他说,为了改善这种情况,首先要认识到社区目前存在的问题;甚至哪怕仅仅在这个演讲中让大家同意这个问题是真实存在的,那他的演讲也算是成功了。为了能识别出这些问题,他根据一些用在计算机网络的指标(metrics)中得到启发,提出了可以使 KVM 成为一个成功的社区的四个特征:低延迟(low latency)、高效率(high efficiency)、更好的监控(better monitoring)和更多的耐久性(more durability)。

Metrics

低延迟,意味着从编写代码到 review 和 merge 的时间要更短。高延迟也许是 KVM x86 的最大问题,这是因为等待 review 的时间很长,并且有很多为了引起维护者的注意而发送的 "ping" 信息。这导致了开发者有挫败感;同时也影响了 KVM downstream 使用者的项目进度计划,使得他们更难紧靠 Linux mainline,从而难以实现 upstream first 的工作方式。

在过去十年里,维护代码库的人数基本持平,但贡献者的数量却翻了一番。有一种常见的增加维护者数量的方法就是定义出一些子组件(sub-components),但据 Christopherson 的说法,每个架构的 KVM 代码都太少了,这不可行。经验还表明,将子系统分割得太细会导致代码重复,就像支持英特尔和 AMD 处理器的代码也是独立开发的过程中的情况一样。他认为在近期内不太可能增加维护者的数量。

在过去的两年里,KVM 的 non-merge commit 的数量几乎翻了一番。这主要是由于谷歌(他所在的公司)采用了积极转向 upstream first 的方式,并合并了多年来一直在其内部 fork 分支中的 patch。然而,在所有这些功能合并之后,项目中的活跃程度就不太可能再回到 2020 年之前的水平了。有大量的其他改动正在进行中,而那些由于缺乏 review 资源而被放弃的改动可能可以再次开始着手进行,例如地址空间隔离(address space isolation)或虚拟机自省(virtual-machine introspection)。这就对开发者和维护者提出了很高的要求,要求他们能更高效地完成工作。

开发者的效率也受到了不确定性(uncertainty)的严重影响。为了提高工作效率,开发者和维护者都需要知道他们可以明确知道对方会做哪些工作。如果开发者不知道他们需要运行哪些测试,以及在哪些架构上运行,他们就会发布出更多的有缺陷的 patch;如果没有明确的规则,不知道该根据哪个分支进行开发,他们就不得不在出现冲突时更频繁地重新生成。另一方面,维护者需要清楚地了解已接受 patch 的状态。Christopherson 说,从维护者接受 patch,到相应的 commit 出现在 public tree 上的时间间隔应该很短,因为这是开发者这边的不确定感受的另一个来源。

效率不仅意味着花在实现新功能上的时间更少,而且为了保持不同架构之间的功能平等所需要编写的代码也更少。RISC-V 是最新的一个支持了 KVM 移植的架构,它就有机会来将之前为其他架构编写的代码(例如,管理程序页表管理)改得更加通用,而不是重复实现自己的一套。如果确实按这个方向走,那么跟架构无关的 patch 的数量将在未来增长,而在过去的 10 多年里的数量几乎保持不变;因此,它也将减少跟架构无关的 patch 的数量。

为了确保 KVM 不会出现新的 bug,并确保那些漏网之鱼可以迅速得到 fix,就需要进行监控(monitoring)。KVM 丰富的测试代码对项目来说是一笔巨大的财富,但如果不运行这些测试,那么同一个 bug 就会被多个用户和开发人员遇到、花时间调试,甚至花时间 fix,这对项目没有帮助。

看一下 KVM x86 的提交的话,其中大约有 20-25%的 commit 在 commit 信息中附有 "Fixes" 标签。这个比例随着整体 commit 的数量的加速增长也在同时开始增长。这很可能不是一件坏事:在过去的几年里,"Fixes" 标签在内核开发中使用得越来越普遍,而且开发步伐的加快也包括 fix 大量的老 bug。

但是,"上游里的 KVM 没有完全跟上持续集成这辆列车",Christopherson 说。大多数 KVM 的持续测试(continuous testing)来自于内核里用来测试整个内核的那些的机器人(bot),测试的时间点不够一致,不能作为衡量 KVM 健康状况的依据。在 public tree 上可以进行一个最小测试,但在每个 patch 提交到官方合并队列之前,可以对其进行更细化的测试。

持久性(durability)其实是稳定性(stability)的另一个名称:一个稳定的 hypervisor 程序意味着开发者和维护者的时间不会被用来不断 fix KVM,特别是不会被用来 fix 几年前引入的、长期未被注意的 bug。

提高持久性,并不一定是一件简单的事情,因为这可能需要改变开发者的思维方式。在过去,KVM 经常采用 "good enough" 的方法,但是只在“count in horseshoes”(https://en.wiktionary.org/wiki/close_only_counts_in_horseshoes),还是在 KVM 中也算?当 KVM 的功能相对较少时,这种方法是有效的,但最终这些快速解决方案甚至在意想不到的地方开始互相影响了,或跟 guest 操作系统的改动也相互关联了起来。事实上,在 x86 上有一个 API 可以禁用 "quirks",这些 quirks 是在 KVM 虚拟机中存在、但在实际硬件上却没有的的处理器行为。

即使一个快速解决方案仍然是有效的,社区也经常会因为人员变动而忘记掉当时的细节。在所有为 KVM 贡献了超过三年、超过 20 多个 commit 的人中,只有五个人仍然活跃在相关开发中。这些 good-enough 的代码对项目的 stability 造成了长期的负担。除非社区对这些快速解决方案能勤劳地记录下来,否则这些知识就会丢失,并且必须通过艰苦学习来重新发现。不仅仅是学习 KVM 做了什么,而是它为什么会有这样的行为。

How to improve?

在列举了可能危及 KVM 开发社区的健康的这些问题之后,Christopherson 接着描述了解决这些问题的五个方法。其中许多改进措施并不限于 KVM,而是可以更普遍地应用于其他 Linux 子系统,甚至其他开源项目。

首先是记录下开发人员能保持高效工作所需的一切信息。这在本次演讲的第一部分中是一个永恒的主题:patch lifecycle、对开发者的测试要求(testing requirement)、关于零散测试(flaky tests)的期望、以及不遵照架构规范的这些内容中都已经提到了,这些都是应该被明确写下来的内容。他还建议将 Linux 发布周期中 review 和接受 patch 的关键日期记录下来,这样维护者就不会觉得有必要在最后一刻塞一个 patch 进来,从而避免搞砸。消除不确定性可以避免维护者忽视某些开发者或功能而导致开发者抱怨,从而消除摩擦。

解决方案的第二个点是测试。开发者的勤奋测试是提高维护者效率的主要因素:许多提交上来的 patch 中问题是在维护者运行 kvm-unit-tests 或 KVM self test 时发现的,因为开发者在提交前从未运行过这些测试。在过去的几年里,新功能都应该伴随着相关的测试,这一点被执行得越来越严格;但是,开发者不应该为了讨好维护者而编写一些最小实现的测试内容,而是应该利用测试来自己寻找 bug,在可能的情况下使用暴力破解,甚至故意引入 bug 来验证测试是否能抓住它们。测试也可以作为文档,指出代码中的一些边缘情况。

很重要的是,测试要容易编写,不需要太多的模板代码。虽然开发人员不太可能对编写测试感到兴奋,但框架不应该妨碍他们来写测试代码。这对于 KVM self-tests framework 来说尤其如此,它允许精确地描述测试场景,但这也可能是一个令人望而生畏的方法。

第三点是分享(sharing)。必须在跨架构的代码共享方面投入更多的精力。通用的问题应该一次解决,把代码合并起来而不是写重复的代码。只有当维护者熟悉多种架构并建议从一开始就共享代码时,才能做到这一点。Christopherson 建议作者本人(作为 KVM 的总体维护者),减少自己在 X86 方面的责任,而是把精力放在这个问题上,这样就可以训练下一代维护者能在一个跨架构工作成为常态的代码库中工作了。事实上,在演讲的时候,这种转变已经在进行中了。

第四项改进是自动化执行集成测试以及开发者测试,以便尽快捕捉到 bug。这减少了 KVM 的 "停机时间",也就是说开发代码的最新版本被破坏,从而无法合并新的变动的时间。虽然这些事件很少发生,但它使贡献者更难完成他们的工作。

讲座结束后,Christopherson 被问及如何让开发者遵循他的建议并使他们的工作自动化。他的回答是,社区不仅包括内核开发者,还有一些人对配置自动化环境很有研究。他们可以在这方面帮助到社区中所有人。他还提到了重新发明测试自动化轮子似乎是 Linux 开发者的一种 "仪式";他建议有经验的开发者尝试分享测试方法和脚本,或者一些方便的 Git alias 命令,尽管它们不太可能成为上游内核源代码的一部分。

他最后的建议是要适应不断变化的环境。人们共同关注代码和社区的 durability,就意味对新功能的开发采取不同的方法。Christopherson 强调说,作为一项规则,新功能应该根据硬件规格书来实现,并且不对 guest 的行为进行任何假设。虽然总是会由于一些不容易(或根本不可能)虚拟的功能而导致例外,但遵循硬件规范就可以使开发人员不必把上述假设写成文档了。尽管处理器手册有很多缺陷,但它们比 KVM 文档还是要先出现的,因此 KVM 文档可以专注在描述真实硬件和虚拟机之间的差异。

在此基础上,当新问题出现时,开发者应该大声说出来,并对流程和文档提出改进建议,这样就不会再发生了。即使他们的建议没有被接受,他们至少会得到一个解释,说明为什么要这样做。

Conclusions

KVM 在规模和复杂性方面的增长对社区和维护者来说无疑是一种挑战;谷歌将以前内部的 KVM patch 上传到 upstream 的做法让 Christopherson 明白了这一点。解决讲座中描述的挑战将使 KVM 开发者更容易为新技术和虚拟化的新的使用场景提供支持,并将其提供给全世界的个人用户以及云计算供应商。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值