报告回归

我们不引入回归”是 Linux 内核开发的第一条规则;Linux 创始人兼首席开发者 Linus Torvalds 亲自确立了这条规则并确保其被遵守。

本文介绍了该规则对用户的意义,以及 Linux 内核的开发模式如何确保处理所有报告的回归;有关内核开发人员的相关内容请参见 处理回归

重点内容(又称“简而言之”)

  1. 如果某个在某个 Linux 内核版本下运行良好的功能在较新版本中性能变差或完全无法工作,这就是回归。注意,较新的内核必须使用相似的配置进行编译;下面的详细解释更详细地说明了这一点和其他注意事项。

  2. 按照 报告问题 中概述的内容报告您的问题,它已经涵盖了回归的所有重要方面,为方便起见,下面再次列出。其中有两点非常重要:将报告的主题以 “[REGRESSION]” 开头,并抄送(CC)或转发给 回归邮件列表 (regressions@lists.linux.dev)。

  3. 可选但推荐:在发送或转发报告时,通过像这样指定回归开始的版本,让 Linux 内核回归跟踪机器人 “regzbot” 跟踪此问题

    #regzbot introduced: v5.13..v5.14-rc1
    

与用户相关的 Linux 内核回归的所有细节

重要的基础知识

什么是“回归”以及什么是“不引入回归”规则?

如果某些应用程序或实际用例在某个 Linux 内核下运行良好,但在使用相似配置编译的较新版本中运行变差或完全无法工作,这就是回归。“不引入回归”规则禁止这种情况发生;如果意外发生了,导致该问题的开发人员应迅速修复此问题。

因此,当 Linux 5.13 中的 WiFi 驱动程序工作正常,但在 5.14 中完全无法工作、显著变慢或出现某种异常行为时,这就是回归。如果一个完美运行的应用程序在较新内核版本中突然表现出异常行为,这也是回归;此类问题可能是由 procfs、sysfs 或 Linux 提供给用户态软件的众多其他接口之一的更改引起的。但请记住,如前所述:本例中的 5.14 需要使用类似于 5.13 的配置进行构建。这可以通过使用 make olddefconfig 来实现,下面将对此进行更详细的解释。

请注意本节第一句中的“实际用例”:尽管有“不引入回归”规则,开发人员仍可自由更改内核的任何方面,甚至更改面向用户态的 API 或 ABI,只要没有现有的应用程序或用例被破坏。

还要注意,“不引入回归”规则仅涵盖内核提供给用户态的接口。因此,它不适用于内核内部接口,如模块 API,一些外部开发的驱动程序使用该接口来挂载到内核中。

如何报告回归?

只需按照 报告问题 中概述的内容报告问题,其中已经描述了要点。其中概述的以下几个方面与回归特别相关

  • 在检查现有的报告以加入其中时,还请搜索 Linux 回归邮件列表存档regzbot 的 Web 界面

  • 将您的报告主题以 “[REGRESSION]” 开头。

  • 在报告中,明确指出最后一个正常工作的内核版本和第一个出错的版本。理想情况下,尝试使用二分查找(bisection)找出导致回归的确切更改,如下文所述。

  • 记得让 Linux 回归邮件列表 (regressions@lists.linux.dev) 知道您的报告

    • 如果您通过邮件报告回归,请抄送回归列表。

    • 如果您向某些 Bug 跟踪系统报告了回归,请通过邮件将提交的报告转发给回归列表,同时抄送相关子系统的维护者和邮件列表。

    如果这是稳定版或长期支持系列中的回归(例如 v5.15.3..v5.15.5),请记得抄送 Linux 稳定版邮件列表 (stable@vger.kernel.org)。

如果您成功执行了二分查找,请将问题提交信息中以 “Signed-off-by:” 开头的行所提到的所有人加入抄送列表。

在抄送或转发报告到列表时,考虑直接将您的报告告知前述的 Linux 内核回归跟踪机器人。为此,请在邮件中包含类似如下的段落

#regzbot introduced: v5.13..v5.14-rc1

Regzbot 随后会将您的邮件视为在指定版本范围内引入的回归报告。在上述情况下,Linux v5.13 仍然运行良好,而 Linux v5.14-rc1 是您遇到该问题的第一个版本。如果您执行了二分查找以找到导致回归的提交,请改指定罪魁祸首的提交 ID

#regzbot introduced: 1f2e3d4c5d

放置这样一个“regzbot 命令”符合您的利益,因为它能确保报告不会被遗漏而无人注意。如果您省略了这一点,只要您向回归邮件列表发送了副本,Linux 内核回归跟踪器就会负责将您的回归告知 regzbot。但回归跟踪器只是一个人,有时他需要休息,或者偶尔也喜欢享受一下远离电脑的时光(听起来可能有点疯狂)。因此,依赖此人会导致不必要的延迟,在此期间回归才会出现在 被跟踪且未解决的 Linux 内核回归列表 以及 regzbot 发送的每周回归报告中。此类延迟可能会导致 Linus Torvalds 在决定“是继续开发还是宣布完成并发布最终版本?”时不知道重要的回归。

是否真的修复了所有的回归?

几乎所有的回归都修复了,只要引起回归的更改(“罪魁祸首提交”)被可靠地识别出来。有些回归无需这样做即可修复,但通常这是必需的。

谁需要寻找回归的根本原因?

受影响代码区域的开发人员应该尝试自行定位罪魁祸首。但对他们来说,这往往无法通过合理的努力做到,因为相当多的问题只发生在开发人员触及不到的特定环境中——例如,特定的硬件平台、固件、Linux 发行版、系统配置或应用程序。这就是为什么最终往往需要由报告者来定位罪魁祸首提交;有时用户甚至可能需要在事后运行额外的测试来精确定位根本原因。开发人员应在力所能及的地方提供建议和合理的帮助,使普通用户能够相对容易地完成这一过程。

如何找到罪魁祸首?

执行二分查找,如 报告问题 中大致概述的那样,并在 二分查找回归 中作了更详细的描述。这听起来可能有很多工作要做,但在许多情况下能相对较快地找到罪魁祸首。如果可靠重现该问题很困难或耗时,请考虑与其他受影响的用户合作,共同缩小搜索范围。

当遇到回归时,我可以向谁寻求建议?

向回归邮件列表 (regressions@lists.linux.dev) 发送邮件,同时抄送 Linux 内核回归跟踪器 (regressions@leemhuis.info);如果该问题最好私下处理,请随意省略列表。

关于回归的更多细节

“不引入回归”规则的目标是什么?

用户在更新内核版本时应该感到安全,不必担心某些东西会损坏。这符合内核开发人员的利益,他们希望使更新具有吸引力:他们不希望用户停留在已被放弃或超过一年半的稳定版或长期支持 Linux 系列上。这符合每个人的利益,因为 这些系列可能存在已知漏洞、安全问题或其他在以后版本中已经修复的有问题方面。此外,内核开发人员希望让用户能够简单且有吸引力地测试最新的预发布版或正式版。这同样符合每个人的利益,因为如果在引入问题后不久就报告问题,跟踪和修复问题就会容易得多。

在实践中真的遵守“不引入回归”规则吗?

这受到了非常严肃对待,从 Linux 创建者兼首席开发者 Linus Torvalds 的许多邮件列表帖子中可以看出这一点,其中一些帖子在 处理回归 中有引述。

这条规则的例外情况极其罕见;在过去,当开发人员认为某种特定情况需要例外时,几乎总是证明他们是错的。

谁来确保真正遵守“不引入回归”规则?

子系统维护者应该负责这一点,他们受到树维护者的监督和支持——例如主线由 Linus Torvalds 负责,各种稳定版/长期支持系列由 Greg Kroah-Hartman 等人负责。

所有这些人都有那些试图确保没有回归报告被漏掉的人的帮助。其中一人是 Thorsten Leemhuis,他目前担任 Linux 内核的“回归跟踪器”;为了促进这项工作,他依赖于 regzbot(Linux 内核回归跟踪机器人)。这就是为什么您希望通过将每个报告抄送或转发给回归邮件列表来将您的报告纳入这些人的视线,理想情况下,在邮件中包含一个“regzbot 命令”以使其立即被跟踪。

通常多快能修复回归?

开发人员应尽快修复任何报告的回归,以便及时向受影响的用户提供解决方案,并防止更多用户遇到该问题;尽管如此,开发人员需要投入足够的时间和精力来确保回归修复不会引起额外的破坏。

因此,答案取决于各种因素,如回归的影响、其存在的时间或发生它的 Linux 系列。不过归根结底,大多数回归应该在两周内修复。

如果通过更新某些软件可以避免该问题,这算不算回归?

几乎总是:是的。如果开发人员告诉您不是这样,请按照上述说明向回归跟踪器寻求建议。

如果较新的内核运行较慢或消耗更多能量,这算不算回归?

是的,但差异必须是显著的。因此,微基准测试中 5% 的减速不太可能符合回归的资格,除非它也会对广泛基准测试的结果产生超过 1% 的影响。如有疑问,请寻求建议。

更新 Linux 时,如果外部内核模块损坏,这算不算回归?

不算,因为“不引入回归”规则是关于 Linux 内核提供给用户态的接口和服务的。因此,它不涵盖构建或运行外部开发的内核模块,因为它们在内核空间运行,并使用偶尔更改的内部接口挂载到内核中。

如何处理由安全修复引起的回归?

在极其罕见的情况下,修复安全问题无法避免引入回归;这些修复会被放行,因为它们终究是两害相权取其轻。幸运的是,这种情况几乎总是可以避免的,因为受影响区域的关键开发人员以及 Linus Torvalds 本人通常都在竭尽全力在不引起回归的情况下修复安全问题。

如果您不幸遇到了这种情况,请检查邮件列表 archives,看看人们是否已尽最大努力来避免回归。如果没有,请报告它;如有疑问,请按照上述说明寻求建议。

如果修复某个回归不可避免地会引起另一个回归,会发生什么?

遗憾的是,这种事情会发生,但幸运的是并不常见;如果发生这种情况,受影响代码区域的专家开发人员应该调查此问题,以找到能够避免回归或至少减轻其影响的修复方案。如果您遇到这种情况,请做前面针对安全修复引起的回归所概述的事情:检查之前的讨论,看人们是否已经尽了最大努力,如有疑问则寻求建议。

顺便简要提一句:如果人们定期对每个开发周期的主线预发布版(例如 v5.15-rc1 或 -rc3)进行测试运行,这些情况是可以避免的。最好的解释是想象一下在 Linux v5.14 和 v5.15-rc1 之间集成的某个更改导致了回归,但同时它又是针对 5.15-rc1 应用的其他某项改进的硬性要求。如果在发布 5.15 之前有人发现并报告了该回归,所有这些更改通常都可以直接被回滚,从而解决回归。几天或几周后,这种解决方案可能会变得不可能,因为某些软件可能已经开始依赖于后续更改之一所引入的方面:回滚所有更改将导致该软件的用户面临回归,因此这是不可能的。

如果我依赖的某些功能在几个月前被移除了,这算不算回归?

算是,但由于上一节概述的方面,通常很难修复此类回归。因此,它需要视具体情况处理。这是每个人都应该定期测试主线预发布版的另一个原因。

如果我似乎是唯一受影响的人,“不引入回归”规则还适用吗?

适用,但仅限于实际使用:Linux 开发人员希望能够自由地移除对只能在阁楼和博物馆里找到的硬件的支持。

注意,有时为了取得进展,回归是无法避免的——而后者是防止 Linux 停滞不前所必需的。因此,如果似乎只有极少数用户受到回归的影响,为了更大的利益,放任不管可能符合他们及所有其他人的利益。特别是如果有一种简单的方法可以绕过该回归,例如通过更新某些软件或使用为此目的而专门创建的内核参数。

回归规则也适用于 staging 树中的代码吗?

根据 涵盖所有 staging 代码的配置选项的帮助文本,情况并非如此,该文本自早期以来就规定

Please note that these drivers are under heavy development, may or
may not work, and may contain userspace interfaces that most likely
will be changed in the near future.

尽管如此,staging 开发人员通常仍会遵守“不引入回归”规则,但有时会为了取得进展而变通它。例如,这就是为什么当 staging 树中的 WiFi 驱动程序被从头编写的完全不同的驱动程序替换时,一些用户不得不应对(通常可忽略的)回归。

为什么较新的版本必须“使用相似的配置进行编译”?

因为 Linux 内核开发人员有时会集成已知会导致回归的更改,但会将其设为可选并在内核的默认配置中将其禁用。这种技巧允许取得进展,否则“不引入回归”规则会导致停滞。

例如,考虑一项新的安全功能,它阻止访问某些常被恶意软件滥用的内核接口,而同时运行少数很少使用的应用程序又需要这些接口。上述方法让双方都很高兴:使用这些应用程序的人可以关闭新的安全功能,而其他所有人都可以启用它而不会遇到麻烦。

如何创建与旧内核类似的配置?

使用已知良好的内核启动您的机器,并使用 make olddefconfig 配置较新的 Linux 版本。这使得内核的构建脚本将运行中的内核的配置文件(“.config”文件)作为您即将编译的新内核的基础;之后,它们会将所有新的配置选项设置为其默认值,这应会禁用可能导致回归的新功能。

我可以报告在使用预编译的纯净版内核时发现的回归吗?

您需要确保较新的内核使用与旧内核类似的配置文件编译(见上文),因为构建它们的人可能为较新的内核启用了某些已知不兼容的功能。如有疑问,请将此事报告给内核提供者并寻求建议。

关于使用 “regzbot” 进行回归跟踪的更多信息

什么是回归跟踪,为什么我应该关心它?

像“不引入回归”这样的规则需要有人来确保它们被遵守,否则它们会由于无意或故意而被破坏。历史表明,这对于 Linux 内核开发来说同样是真的。这就是为什么 Linux 内核的回归跟踪器 Thorsten Leemhuis 以及一些人试图通过密切关注所有回归直到它们被解决来确保它们得到修复。他们都没有为此获得报酬,这就是为什么这项工作是基于尽力而为的原则完成的。

为什么要以及如何使用机器人跟踪 Linux 内核回归?

由于 Linux 内核开发过程的分布式和松散结构性质,完全手动跟踪回归已被证明相当困难。这就是为什么 Linux 内核的回归跟踪器开发了 regzbot 来促进这项工作,其长期目标是为所有相关人员尽可能自动化回归跟踪。

Regzbot 的工作原理是监视对跟踪回归报告的回复。此外,它还在寻找引用了此类报告且带有 “Link:” 标签的已发布或提交的补丁;对此类补丁发布的回复也会被跟踪。结合这些数据,可以深入了解修复过程的当前状态。

如何查看 regzbot 目前跟踪哪些回归?

请查看 regzbot 的 Web 界面

regzbot 应该跟踪哪类问题?

这个机器人旨在跟踪回归,因此请不要让 regzbot 参与普通问题。但如果您让 regzbot 跟踪严重问题(如关于挂起、数据损坏或内部错误的报告:Panic、Oops、BUG()、警告等),Linux 内核的回归跟踪器是认可的。

如何更改被跟踪回归的各个方面?

通过在对包含报告的邮件进行直接或间接回复时使用“regzbot 命令”。最简单的方法:在您的“已发送”文件夹或邮件列表存档中找到报告,并使用您的邮件客户端的“全部回复”功能进行回复。在该邮件中,在单独的段落中使用以下命令之一(换句话说:使用空行将一个或多个这些命令与邮件其余部分的文本隔开)。

  • 更新回归开始发生的时间,例如在执行二分查找之后

    #regzbot introduced: 1f2e3d4c5d
    
  • 设置或更新标题

    #regzbot title: foo
    
  • 监控讨论该问题的其他方面或修复方案的讨论或 bugzilla.kernel.org 工单:

    #regzbot monitor: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
    #regzbot monitor: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
    
  • 指向包含其他感兴趣细节的地方,例如与此略有关系但主题不同的邮件列表帖子或缺陷跟踪器中的工单

    #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
    
  • 将回归标记为无效

    #regzbot invalid: wasn't a regression, problem has always existed
    

Regzbot 支持其他一些主要由开发人员或回归跟踪人员使用的命令。关于它们以及上述 regzbot 命令的更多细节,可以在 regzbot 的 入门指南参考文档 中找到。