一个补丁迭代了16个版本后被撤,我的 Linux内核之旅!

e3304cec7e63f6358524eabbc2a34af1.gif

【CSDN 编者按】一个好的开源项目,能够成长为一个全球性的开源项目,肯定有它的独特魅力所在。Linux内核守护者吴峰光博士特别为《新程序员001:开发者的黄金十年》撰文,生动细致地分享了他早年为Linux Kernel提交I/O预读取算法补丁的经历,过程颇为波折有趣,从中可以一窥Linux成为全球最大开源项目的关键。

作者 | 吴峰光       责编 | 张红月

出品 | 《新程序员》编辑部

Linux内核开发者社区普遍被认为是一个大神云集、充满挑战的社区,不仅是这个社区对于代码质量的高度挑剔,也因为网络上盛传这一项目的发起人——Linus Torvalds,是一个脾气不太好的“独裁者”:每一次他在邮件列表里发飙“骂人”,都会成为不大不小的新闻事件,让每一位好奇Linux项目的开发者们交头接耳。

0a26d3f57b8d318038a7260029e5ea3e.png

Linus Torvalds,图片来源于2022年开源峰会活动

那些充满骄傲的黑客们,四处传颂着他那句“Talk is cheap, show me the code”,昂首挺胸地游走在各个社区之间。

与此同时,虽然开源社区已经发展了这么多年,但要说是否有另外一个开源项目达到了Linux这样的成就,其答案至今仍然是否定的,Linux仍是软件领域最为成功的开源项目,没有之一。

1991年的那个夏天,当时就读于赫尔辛基大学的Linus Torvalds 21岁,在Usenet上发布了那篇著名的帖子,开启了他的奇妙人生,也改变了更多年轻人的未来。1999年,在Linux诞生的8年后,还在中科大自动化系读大三的我第一次接触到Linux,成为一名Linux用户。6年后,读到博士的我向Linux内核社区提交了人生中第一个内核补丁。本来,只是为了完成自己的论文,本着实用化的想法,将补丁提交给社区。然而,这个对I/O预读取算法进行改进的补丁却是一块超出我预估的硬骨头。从一开始丢入社区中无人问津,到经受挑战,再到反复修改,差不多每个月都提交一两次迭代版本,历经将近两年的时间,在迭代了十多个版本之后终于被社区接受。

不打不相识,毕业后,我正式走上了Linux内核开发这条职业道路。

bd80b8d19aecc672c977bfd3d7211cce.jpeg

吴峰光,博士毕业于中国科学技术大学自动化系。先后工作于Intel与华为。开源贡献包括:2007 Linux Kernel I/O预读算法、2010 Linux Kernel回写算法、2013 LKP(Linux Kernel Performance)内核性能测试、2018 Memory-optimizer冷热内存检测与透明迁移解决方案、2020 Compass-CI开源软件全栈测试平台、2021 openEuler开源操作系统技术委员会成员等。

a842daadfb46ecca786f4b23ae4b6290.png

初见Linux内核

我第一次近距离接触Linux比较有意思,是有人拿着一张Linux光盘来让我帮忙安装。我顺着安装程序的一步步英文提示的指引,居然成功了,然而重启后就抓瞎了,不知道该怎么用。

之后,我的同学弓岱伟就充当了我的Linux导师,他在Linux控制台里噼里啪啦打命令,满屏幕的英文输入输出让人目不暇接——真真Linux大玩家! 我很喜欢搬一个板凳默默坐在他一旁,跟着他在这个新世界里徜徉。

我是幸运的:这可能是最为轻松而有趣的一种Linux入门方式了!对于不玩游戏的我来说,GNU/Linux系统就是我的“游戏世界”:探索、挑战,新鲜感、成就感。一般游戏的引人之处,Linux亦可带来相似的满足感。更让人兴奋的是,身边有志同道合的人一起交流学习,将来还能对接实验室、学校、社会的需求。这符合人的本性,就像是小小孩热衷于追着大一点的小孩求带着玩一样,跟志同道合的人一起玩Linux,比独乐乐有意思太多。

从此,我与Windows下的OWL/MFC拜拜了。之后很自然地,我也以类似的方式影响了身边的有缘人。这是属于程序员的美丽新世界——Shell/Vim等命令行工具一旦掌握,就效率飞起;GNU/Linux开放源代码,工具链齐全,对开发者的可玩性太高了;UNIX系统小而美工具集的组合设计理念,经受了历史考验,一旦学会终身受用。

那时候我们跑Slackware,两个寝室之间拉一根网线,内网互联,尝试各种服务。后来我们在瀚海星云BBS找到了LUG组织,就玩得更嗨,还在校园里玩Debian安装大会。进实验室后,我们搭起了PXE网络启动服务,校园网各处的电脑,可以免安装启动进入KNOPPIX等Linux系统。我们独家优化的FTP服务器,百倍提速,开启了全校的文件分享盛宴。

在又一次机缘巧合之下,我开始触及Linux Kernel代码。

2005年读博期间,我在实验室做的流媒体服务器项目,遭遇了并发能力不足的问题。随着排查的深入,我闯入了内核I/O领域:原来是其中的I/O预读取(readahead)算法代码没有按预期检测出的顺序读,导致大量低效的小I/O。

我尝试自己修改内核代码后,问题被修复,效果令人振奋!好东西要分享呀!于是我屁颠屁颠地去给Linux社区提交补丁。

197e5ed9d0ed58d3ba9b73727211c409.jpeg

本文节选自《新程序员001:开发者的黄金十年》

2cf0104e00eb9903e7da7c492263f3d6.png

几经波折的填坑之路

那时我已经非常认可开源的理念:自由使用、分发,修改、回馈。当Linux用户遇到了问题,就能以Bug report或Bug fix的方式,回馈上游社区,从而形成一个越用越好的正向循环。所以,搭了多年免费班车的我,现在亲历一个坑,责任感油然而生:是时候帮忙填坑了!(只不过当时的我还没有意识到这是个多么庞大的坑!)

要填坑,第一件要做的事情是啥?是转变角度:不能仅仅以服务自己单位项目为目标,草草搬个木板,让项目之车能快速通过就了事——那叫Hack,显然上不了台面。需要正儿八经地研究I/O预读取周边代码,研究过去的邮件讨论,搞清楚它的设计目标、思路、来龙去脉,还有非常重要的:各种场景下的行为表现。这意味着大量测试和假设/验证迭代,在此基础上形成新的方案(Linux社区主要在Mailing list展开公开讨论,这就为我这种潜水爱好者提供了极好的观摩学习机会)。

然而当时的我还不懂太多道理,只知其一,不知其二。当心怀兴奋与忐忑,敲下邮件发送命令之后,首先面对的第一重考验就是:沉默。

邮件如泥牛入海,没有收到任何反馈。

我想没关系,没有收到反馈一定是因为代码还不够好,咱继续测试和改进代码。就这样,V2、V3、…… 补丁集越发越庞大。在默默发了几个版本之后,终于,来自Andrew Morton的一份邮件打破了宁静:

cf2faea7ebd070cdcd41d5b37cde5f5c.png

(备注:Andrew Morton是内核社区-mm tree的maintainer,主管质量的二号人物。他邮件大意是:这个补丁可真大!而且预读这个事情本身就超级复杂。我已经找了两位兄弟Ram Pao和Steve Pratt帮忙一起审查和测试了,但是这要花时间。)

从这里可以看出,Linux社区最稀缺的资源是两个:代码审查(Review)和测试(Testing)。我也是那个时候才知道,社区鼓励发小而美的补丁——抛出一大坨令人望而生畏的补丁集,很容易劝退查看者(至少会让人产生“等我有大块空闲时间了再来消化”的想法)。

新人发补丁最担心什么?有人挑战、挑毛病?或者更糟,无人理会?而更深层次的问题,是面对一个新社区,心虚没底,没感觉,没品位。解决办法,一是潜水学习,二是投身其中。新人发补丁的最佳策略,是从小修复开始:“这儿有个缺陷,这个小补丁可以修复”,接下来社区的交互就会比较顺,不容易遭遇重大挫折。

在这一点上,我显然犯错了。

但我又极其幸运,因为不久之后,Andrew Morton开始正式审查我的补丁。从此,我与他结下了不解之缘,可以说他正是我在Linux Kernel的领路人。

我逐渐学会了从社区视角来看问题:Linus Torvalds及其维护者(Maintainer)团队,他们需要什么样的补丁?不欢迎什么样的补丁?

“我们公司/项目需要xxx,所以写了这个配套补丁希望合入Linux。”这是一种以公司为中心的视角。抱歉,在社区看来,上述描述是一种政治不正确。

Linux现在的主要贡献都来自各家公司的雇员,这可能是世界上最广泛的一个跨公司合作开源项目。那么,Linux社区如何协调和引导如此众多的公司完成协作,避免冲突?这是个不小的挑战,尤其是其中有不少互为竞争对手的公司,在一些热点问题上可能希望竞争主导权、话语权,以及有利于自身的实现。

对此,Linus Torvalds作为“独裁者”的作用就体现出来了:你们都愿意投人来做xxx,很好!选择做什么,是你们的自由。但是!最终怎么做,我的地盘我做主,要遵从社区的原则来做。

最大的原则就是:所有开发者/贡献者,摘掉你们所属公司的帽子,戴上“独立贡献者”的帽子,按照技术本来的最佳实践,去做设计与实现。大家都以“独立贡献者”的角度参与审查。

换言之,公司从商业竞争力角度,选择“做正确的事”;社区从技术通用性角度,确保“把事情做正确”。这就是开源社区与商业公司的基本合作共识。除了倡导大家做“独立贡献者”,Linux社区还有“看门人”的逻辑。Linux社区人来人往,每天补丁与话题无数,像是个热闹的市集;开放的邮件列表,谁都可以订阅,观摩;谁都可以冲进来,发布一个补丁,或者对一个补丁发表自己的看法。在这纷纷纭纭之中,对补丁贡献的质量控制,必须极为严格。

在Linux社区,质量控制的核心在于“代码合入”(Git Merge)这一动作,这是属于“看门人”的唯一权力。合入是一个重要的门槛和分水岭。在合入之前,看门人有是否接受、何时合入的决断权,以及在此基础上衍生的关于补丁实现原则/方案的建议权。此时看门人的权威一面,想必给贡献者们留下了深刻印象。可是在合入之后,强势的看门人,随即变身为苦命的维护者,这是因为开源社区有一个基本假设:在开源市集里,贡献者们进进出出,随时可能走掉,不再响应。这意味着合入代码所增加的系统复杂性,其长期维护责任,要由社区与维护者来兜底。

“Linux有xxx问题,影响了xxx用户/场景。这个补丁效果好,副作用小,通用,是长期演进方向。”这,才是看门人喜闻乐见的补丁。

I/O预读取补丁集前后发了十几个版本,Andrew Morton非常认真地给了一百多份审查邮件,就连Linus Torvalds也回复了十来封邮件,甚至还跃跃欲试,亲手奉上了一个一百多行代码的补丁。

当时我信心满满,以为功能日渐完善,很快会被合入主线。

然而,经历了一年多的开发迭代,到第16个版本发出后,我收到了Andrew的一份邮件,大意是:

我把你的补丁集去掉了,因为它太复杂了!

那一刻犹如晴天霹雳!我整个人都傻了。回过味来,我终于刻骨铭心地体会到了KISS原则的重要性。这可是真正的刻骨铭心!

从一开始,Linux就是简单的。当年Linus第一次发布Linux的时候,并不完善,但是简单能用。及早发布,这是Linux取得成功的一个重要因素。时至今日,虽然Linux日趋庞大和完善,但对于任何一个功能项,这一原则仍然适用,并被看门人坚持。

于是,我决定抛掉原来的代码,重新写一份大大简化了的方案,包括功能与算法,这又花了我几个月的时间。在Andrew Morton的审查下,这些代码又经过了几轮改进。终于,到了2007年的7月19日,那一天我收到了很壮观的几十封邮件,那是Andrew Morton把补丁集发给Linus,然后从-mm tree里移除消息!

  • 380 C Jul 19 Andrew Morton ( 64:0) [patch 048/209] 

    readahead: pass real splice size

  • 381 C Jul 19 Andrew Morton ( 122:0) [patch 049/209] 

    mm: share PG_readahead and PG_reclaim

  • 382 C Jul 19 Andrew Morton ( 240:0) [patch 051/209] 

    readahead: sanify file_ra_state names

  • 383 C Jul 19 Andrew Morton ( 282:0) [patch 050/209] 

    readahead: split ondemand readahead interface into two 

    fun

  • 384 T Jul 19 Andrew Morton ( 69:0) - readaheadintroduce-pg_readahead.patch removed from -mm tree

  • 385 T Jul 19 Andrew Morton ( 109:0) - readaheadadd-look-ahead-support-to-__do_page_cache_readahead.

    patch remo

  • 386 T Jul 19 Andrew Morton ( 66:0) - readaheadmin_ra_pages-max_ra_pages-macros.patch removed from -mm tree

  • 387 T Jul 19 Andrew Morton ( 146:0) - readaheaddata-structure-and-routines.patch removed from -mm tree

  • This patch was dropped because it was merged into mainline or a subsystem tree

这些补丁集终于被合并了!这可真是激动人心的时刻!进入开源世界交互,就像是打开一扇大门。整个过程中,先后有140多位来自世界各地、各种背景的人帮忙审查、测试,在自己的网站上试用并反馈效果;还有人在网上发帖子、晒贴自己的性能数据、图表;有人邀请我在期刊杂志写文章,去技术大会讲,甚至出书……如此广泛和全方位的协作,有效支撑了代码的改进。

这样的支持力度,在一家即使很大的公司里,可能也仅限于重点项目。但是在Linux社区,这样的事情就是日常协作!基于开源协作,任何一个模块都能吸收全世界的能量,并且是自由选择,让最适合的人做最适合的事,让最利益相关的个人与组织做最对口的测试和反馈,从而达到《大教堂与市集》里描述的:市集实质上拥有了压倒性的资源优势,形成对大教堂开发模式的碾压。

这大概就是Linux能够发展为全世界最大的开源项目的生命力源泉吧!

Sai对本文亦有贡献。

本文节选自《新程序员001:开发者黄金十年》,该书特别策划十万亿开发者新生态、家家都是技术公司、人人都是开发者三大版块,为所有开发者带来有技术、有深度、有质量的高品质内容。

0ca25e2c0c1b5e2869a4a10d36863e59.jpeg

— 推荐阅读 —

☞字节跳动正大量招聘芯片工程师或准备自研芯片;Google放缓招聘;Android 13 Beta 4发布|极客头条
☞1 亿美元合同到期,苹果和前设计总监 Jony lve 分道扬镳
☞共赴星辰大海!华为云原生与 AI 开源项目助力根植中国前沿卫星星座计划

版权声明:本文为CrisAppleYan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。