LWN:再次审视stable-kernel里面的质量回退问题!

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

Revisiting stable-kernel regressions

By  Jonathan Corbet

February 13, 2020

原文来自:https://lwn.net/Articles/812231/

stable-kernel的更新通常都是非常可靠的。所以针对stable-kernel的patch的诸多规则中第一条就是“明显正确并且验证通过”。尽管有这样严格的要求,其实在stable kernel的发布过程中,社区里一直有声音在抱怨许多release里面还是引入了一些regression(质量回退,指新引入了bug)。在2016年的时候,LWN就做过分析,介绍了stable release里面存在的regression,不过也指出发生率对大多数人看来其实已经非常低了。在那之后,stable release中合入的patch数量越来越多,现在应该再看看目前的stable kernel中regression的发生率了。

这里举个例子来让大家了解一下stable kernel update会包含多少patch。在4.9.213的时候,比起最早的4.9 release,已经增加了15,648个patch。这个数量已经可以比得上一个新的kernel版本的开发周期的patch数量了。我们无法仔细审查每一个patch来判断它会不会导致regression,哪怕stable update的maintainer也无法说得清。不过有个方法可以自动找出来大多数这种regression patch。

kernel社区一直有个惯例,就是在fix了一个bug的patch中,会加上一个Fixes tag,来指向此前引入bug的那个patch。这个Fixes tag里面会包含此前引入问题的那个patch的commit ID。因为stable kernel release按理来说只应该合入bug fix patch的,大家可能以为几乎所有的patch都带有Fixes tag。不过实际上只有40-60%的commit有Fixes tag,不过这个比例近来还是在逐渐上升的,得益于规则越来越规范了。

所以,可以直接用计算机来查找所有Fixes tag,提取出commit ID来找到引入bug的patch,然后确认一下它们是否也是在stable update过程中合入的,如果是的话,基本可以说原patch有问题,导致了regression,需要后续的bug fix。当然,这里也会有一些细节需要注意,例如stable-kernel里面的commit同合入mainlin(所有的fix都应该是首先合入mainline的)的相同commit,它们的ID并不相同,因此需要能够把两个分支上的commit对应起来,才能确认fix的是哪个commit。还有一些直接revert的patch,一般不会带有Fixes tag,所以这种需要单独搜索出来。还有一些诸如此类的细节要注意。最终的结果里面应该也是有一些噪声没有处理干净的,不过足够作为示意,帮我们了解情况了。

大家可能感兴趣是用什么工具来做的分析,其实是用的专门分析git仓库数据的gitdm工具集里的stablefixes。可以从这里获取git://git.lwn.net/gitdm.git。

在2016年的时候,我们得到的regression rate,在longer-term stable kernel里面是2%左右。而4.4系列kernel当时有1,712 commit,已经有2.3%的regression rate了。在那次分析之后,commit的数量增加了许多,在4.4.213里面已经有14,211个commit了,这些主要得益于更好的开发规范以及更多利用了自动化工具(包括一些机器学习的系统)来发现并一直那些原作者没有想到要发给stable kernel的bug fix patch。我们现在改善了一下脚本,移植到Python 3,然后对当前还在支持的stable kernel运行了一次分析,结果如下:

Series Commits Tags Fixes Reverts
5.4.18 2,423 1,482 61% 74 29
4.19.102 11,758 5,647 48% 588 100
4.14.170 15,527 6,727 43% 985 134
4.9.213 15,647 6,286 40% 951 139
4.4.213 14,210 5,110 36% 834 124

在上述表格中,Series指的是用来分析的stable kernel版本。Commits值得是这个Series里面的commit数量,而Tags就是包含有Fixes tag的commit的数量和占比。Fixes这一列的数字就是那些修正了本次stable release里面新增patch引入的问题的patch数量。Reverts是指那些直接revert掉的patch。有位著名人士说过,revert就是对一个patch提出批评的最真诚的方式。(注:可以参看LWN原文页面表格查看commit细节)。

从这些数字中我们可以看出一些信息,例如,5.4.18中有3%的commit都是在修复其他commit引入的问题,所以有问题的commit比例至少有3%,这里的情况其实不是这么简单的。比如,其实有许多的fix patch是跟引入问题的commit在同一个stable版本里面合入的。也就是说,尽管最初的commit引起了regression,但是其实没有哪个stable release版本是带着这个错误代码的,也就不会有谁真的收到这个bug的影响。所以把这些也算作regression的话,对stable kernel的质量评价来说并不公平。如果去掉这些在同一个release里面合入的fix,结果是下面这样:

Series Fixes

Same

release

Visible

regressions

5.4.18 74 29 45
4.19.102 588 176 412
4.14.170 985 253 732
4.9.213 951 229 722
4.4.213 834 232 602

还有一个因素需要考虑,就是那些没有Fixes tag的commit该怎么算。其中许多其实都是在fix那些之前的patch所引入的bug,不过人们没有去追溯那个bug是怎么出现的。如果上面的表格中的数据被当做一个stable series里面的regression总数的话,那其实就是把这一类没有标记Fixes tag的commit都算作与regression无关了,这样肯定会导致低估了总体的regression fix的数量。换个角度,如果把这些都当做是regression fix,那又会大大高估了regression fix的数量。

所以,最好的方式也许是两种情况都看看,我们基本上可以肯定真正的regression rate应该在两者之间。

Series

Visible

regressions

Regression rate
Low High
5.4.18 45 1.9% 3.0%
4.19.102 412 3.5% 7.3%
4.14.170 732 4.7% 10.9%
4.9.213 722 4.6% 11.5%
4.4.213 602 4.2% 11.8%

所以上面这就是我们能拿到的最解决的范围了。不过这里还有一些很少见的情况。比如mainline commit 4abb951b73ff("ACPICA: AML interpreter: add region addresses in global list during initialization")包含了一个“cc: stable@vger.kernel.org”的tag,所以它在4.19.2 release里面被包含了进来(相应的commit ID是22083c028d0b)。不过后来在4.19.3里面被revert掉了,因为人们抱怨它没有fix什么真正的问题,反而导致了regression。可是在4.19.6的时候它又被人们的要求下加了回来。 在4.19.35里看的话还会看到2个commit:commit d4b4aeea5506解决了一个相关的问题,而在Fixes tag里面指出了upstream分支里的commit,而commit f8053df634d4则声称自己是原来那个upstream的commit,其实早就被打上来了。最后一个看起来像是修复了某个没有做完整的backport。这一系列改动我们该怎么来统计到上面的表格中呢?反正我们是放弃了。

从上面的数据中我们得到了什么结论呢?2016年的时候的regression rate看起来比起现在的要低一点,这意味着stable tree上patch数量的增长不仅是增加了regression的个数,也同时增加了regression rate。这不是一个好的迹象。另一方面来说,人们对stable kernel的regression的抱怨的声音似乎现在越来越少了。也许这是因为人们已经习惯了。或者,也许是那些最坏情况的regression不在出现了,例如文件系统被毁坏这一类,也就是说漏过来的这些bug一般都是比较小的问题。

新的kernel比起更早期的kernel来说会有更低的regression rate。这可以得到两方面的解释。一方面是选择patch来移植到stable kernel的流程越来越完善了,所以引入的regression越来越少。另一方面,也许是这些kernel出现的时间还不长,所以没有完全找出那些regression patch。2016年的文章中查看的4.4.14,当时有39个regression fix(其中19个都是在发布之前就及时fix了)。而现在的4.4.213则找出了110个regression issue,都是在4.4.14之前引入的问题(同样是19个在发布之前被fix)。所以,我们可以肯定5.4.18里的regression数量肯定要比我们上面列出的数字要高。无论如何,看起来短时间内我们都会继续现有的策略,把尽量多的fix都加到stable tree上。这也许是一件好事,如果stable tree有几千个fix但是其中有若干个regression,那它比起一个没有带上这些patch的kernel肯定更加稳定。尽管如此,我们还是需要多注意regression rate。如果regression rate变得太高了,那么就会导致用户越来越不愿用stable update,这肯定不是我们希望看到的情况。

全文完

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

大家顺便来投个票展现一下民意吧:

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

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

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章