Linux 内核回归(Regression)报告指南:从"不引入回归"规则到 regzbot 追踪实战
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
导读:本文基于 Linux 内核官方文档 Documentation/admin-guide/reporting-regressions.rst,系统讲解 Linux 内核开发的"第一规则"——"我们不制造回归"(We don't cause regressions)对普通用户意味着什么:如何准确判断一个问题是否属于回归、如何规范地提交回归报告、如何利用内核回归追踪机器人 regzbot 让报告进入官方追踪队列,以及面对各种边界情况(性能下降、外部内核模块损坏、安全修复引发的回归、staging 树代码等)该如何判断与应对。读完本文,你将掌握一套从"发现异常"到"报告被受理并修复"的完整、可操作的实战流程。
什么是回归?什么是"不引入回归"规则?
Linux 内核创始人兼首席开发者 Linus Torvalds 亲自确立了 "We don't cause regressions"(我们不引入回归)这条规则,并持续确保它被遵守。
回归的精确定义:如果某个应用程序或实际使用场景在旧版 Linux 内核上运行良好,但在使用相似配置编译的更新版本内核上运行变差或完全无法运行,这就构成一次回归。"不引入回归"规则禁止这种情况发生;如果它意外发生,造成问题的开发者应当被要求尽快修复。
例如:
- Linux 5.13 中工作正常的 WiFi 驱动,在 5.14 中完全无法工作、明显变慢或行为异常——这是回归;
- 一个原本运行正常的应用程序在新内核版本上突然出现异常行为——这也是回归,这类问题可能由 procfs、sysfs 或内核向用户态软件提供的众多其他接口的变化引起。
但需要注意两点前提条件:
- 配置相似:本例中的 5.14 必须使用与 5.13 相似的内核配置构建。可以通过
make olddefconfig实现,下文详述。 - "实际使用场景":开发者即使面对"不引入回归"规则,也有权改变内核的任何方面,甚至改变对用户态的 API 或 ABI——只要不破坏任何现有应用或使用场景。换言之,规则保护的是"用户能感知的行为",而非代码或接口本身。
同时要明确规则的边界:"不引入回归"规则只覆盖内核向用户态提供的接口,不适用于内核内部接口(如模块 API),外部开发的驱动程序正是通过这类内部接口挂钩内核的。
重要提示(TL;DR):三条速览
文档开篇为用户提供了三条快速要点:
- 判断:如果某个功能在旧内核上正常、在新内核上变差或失效,即构成回归。注意新内核需以相似配置编译。
- 报告:按照 Documentation/admin-guide/reporting-issues.rst 的流程报告问题(该文档已覆盖回归相关的所有要点)。其中两条尤为关键:报告主题以
[REGRESSION]开头,并抄送(CC)或转发至回归邮件列表regressions@lists.linux.dev。 - 可选但推荐:在发送或转发报告时,通过指定回归发生的时间范围,让 Linux 内核回归追踪机器人 regzbot 追踪该问题:
#regzbot introduced: v5.13..v5.14-rc1上面示例表示:Linux v5.13 仍工作正常,v5.14-rc1 是首次出现问题的版本。如果已经通过 bisection(二分定位)找到引入回归的提交,则直接指定该提交的 commit-id:
#regzbot introduced: 1f2e3d4c5d如何报告回归:完整实操流程
报告回归本质上就是按照通用问题报告指南 Documentation/admin-guide/reporting-issues.rst 来操作,但回归有几个额外要点。以下是完整的报告流程:
1. 报告前的检索与准备
- 检索已有报告:除了常规渠道,还应搜索 Linux regressions 邮件列表 的归档以及 regzbot 的 Web 界面(linux-regtracking.leemhuis.info/regzbot/),看是否已有相同问题的讨论可以加入。如果找到匹配报告,加入讨论而非另发新报告。
- 使用 vanilla(纯净)内核:安装和测试时确保内核是 vanilla 版本(未打补丁、未使用附加模块),并确保内核在健康环境中构建和运行、问题发生前未被污染(tainted)。参见 Documentation/admin-guide/reporting-issues.rst 中关于准备工作与 tainted 检查的说明。
- 独立报告多个问题:如果同时遇到多个内核问题,请分别报告。报告中包含所有与问题相关的信息,如所用内核版本和发行版。
2. 撰写报告:主题与内容规范
- 主题以
[REGRESSION]开头(这是"高优先级问题"的专门处理方式,见 reporting-issues.rst 的 "Special handling for high priority issues" 一节)。 - 清晰说明两个关键版本:最后正常工作的内核版本,以及第一个出现问题的版本。理想情况下,使用 bisection 找到罪魁提交(culprit commit)。
- bisection 成功后:报告主题的第二部分使用引入回归的那个变更的标题,报告中写明罪魁提交的 commit-id;抄送该提交的作者以及提交信息中以
Signed-off-by:开头的行中列出的所有人(即 sign-off 链上的每个人)。 - bisection 未成功时:报告中说明最新测试正常工作的版本(如 5.7)和最早出现问题的版本(如 5.8-rc1)。
3. 发送与抄送规则
- 邮件报告:抄送回归邮件列表
regressions@lists.linux.dev。 - Bug 追踪器报告:如果问题需要提交到某个 Web 追踪器,先提交,然后转发(forward)报告邮件至回归邮件列表,同时抄送相关子系统的维护者及其邮件列表。转发时务必内联报告正文(不要作为附件),并在顶部附上一小段说明,注明对应工单的 URL。
- stable/longterm 系列内的回归:例如 v5.15.3 升级到 v5.15.5 出现问题,记得抄送 Linux stable 邮件列表
stable@vger.kernel.org。
4. 报告发出后的跟进义务
报告发出只是开始。文档明确要求:
- 公开、及时地回应任何询问;
- 测试开发者提出的修复补丁;
- 主动复测:至少在每一个新的 mainline 候选版本(RC)发布时重新测试并回报结果;
- 事情停滞时友好地提醒;
- 如果无人响应或响应不理想,尝试自助解决问题。
5. 用 bisection 定位罪魁提交
如何找到罪魁提交?答案是执行bisection(二分定位)。大致流程见 Documentation/admin-guide/reporting-issues.rst,详细步骤见 Documentation/admin-guide/bug-bisect.rst,新手建议先阅读完整的 Documentation/admin-guide/verify-bugs-and-bisect-regressions.rst。
核心命令序列(摘自 bug-bisect.rst):
git bisect start git bisect good v6.0 git bisect bad v6.1之后每个测试点都执行:
cp ~/prepared_kernel_.config .config make olddefconfig编译安装启动后,若功能正常执行git bisect good,若仍然损坏执行git bisect bad。Git 会打印类似Bisecting: 675 revisions left to test after this (roughly 10 steps)的提示,直到输出... is the first bad commit找到罪魁提交。
重要建议:
- 如果难以可靠复现问题,考虑与其他受影响用户合作,共同缩小搜索范围;
- bisection 时只要判断错一次,后续整个流程就会完全偏离方向,因此在不确定时宁可多花几分钟测试,确保对 Git 的判定是正确的;
- 完成后保存现场以便报告使用:
git bisect log > ~/bisection-log cp .config ~/bisection-config-culprit git bisect reset- 推荐的可选验证:在最新代码库上尝试
git revert --no-edit <culprit-commit-id>回退罪魁提交,若回退后问题消失,即验证了 bisection 的正确性,也为开发者提供了通过 revert 解决回归的路径。
6. 谁负责找到根因?
受影响代码领域的开发者应当自行尝试定位罪魁提交。但对开发者而言,很多问题只出现在其触达不到的特定环境中——例如特定的硬件平台、固件、Linux 发行版、系统配置或特定应用。因此,最终往往需要报告者自己定位罪魁提交,有时甚至需要报告者随后运行额外测试以精确定位根因。开发者应当提供建议并在力所能及的范围内提供合理帮助,让这一过程对普通用户来说相对轻松、可达成。
7. 遇到问题可以咨询谁?
向回归邮件列表regressions@lists.linux.dev发送邮件,同时抄送 Linux 内核回归追踪员(regressions@leemhuis.info);如果问题更适合私下处理,可以省略列表。
让 regzbot 追踪你的回归:命令全解
为什么需要回归追踪?
规则需要有人确保被遵守,否则规则会被有意或无意地破坏。Linux 内核发展史证明了这一点。为此,Linux 内核回归追踪员 Thorsten Leemhuis 与一些人共同确保所有回归在解决前都被持续关注,直到其被修复。由于内核开发过程高度分散、结构松散,完全手工追踪已被证明极其困难,因此 regzbot 应运而生——其长期目标是为所有参与者尽可能自动化回归追踪。
regzbot 的工作方式:监视被追踪回归报告的回复;同时,它还会寻找通过Link:标签引用这些报告的已发布或已提交补丁,并同样追踪这些补丁帖子的回复。综合这些数据,regzbot 能够很好地反映修复过程的当前状态。
为什么你应该让 regzbot 追踪你的报告?
在你的邮件中加入 "regzbot command" 符合你自己的利益,因为它能确保报告不会悄无声息地石沉大海。如果你省略这一步,Linux 内核的回归追踪员会在你抄送回归邮件列表后替你告知 regzbot——但追踪员只是一个人,有时需要休息,偶尔甚至想暂时离开电脑(听起来很疯狂,但确实如此)。依赖这一个人会导致你的回归被列入追踪列表(及 regzbot 的每周回归报告)的时间被不必要地推迟。这种延迟可能导致 Linus Torvalds 在决定"继续开发还是收尾发布最终版本"时,对重要的回归一无所知。
完整的 regzbot 命令参考
在报告的直接或间接回复中使用 'regzbot command'。最简单的方式:在你的"已发送"文件夹或邮件列表归档中找到报告邮件,用邮件客户端的"全部回复"(Reply-all)功能回复它。以下命令必须放在独立段落中(即用空行将这些命令与邮件正文的其余部分分隔开):
| 命令 | 作用 |
|---|---|
#regzbot introduced: 1f2e3d4c5d | 更新回归开始发生的时间,例如 bisection 之后(也可用v5.13..v5.14-rc1形式指定版本范围) |
#regzbot title: foo | 设置或更新回归的标题 |
#regzbot monitor: <URL> | 监视讨论该问题或修复的邮件线程或 bugzilla.kernel.org 工单(monitor 仅对 lore.kernel.org 与 bugzilla.kernel.org 有效) |
#regzbot link: <URL> | 指向带有更多相关细节的位置,如略有相关但主题不同的邮件列表帖子或追踪器工单 |
#regzbot invalid: wasn't a regression, problem has always existed | 将回归标记为无效 |
regzbot 还支持一些主要由开发者或回归追踪人员使用的其他命令,以及上述命令的更多细节,可参见 regzbot 的入门指南与参考文档。
regzbot 适合追踪哪些问题?
regzbot 设计用于追踪回归,因此请不要为普通问题启用 regzbot。但对严重问题(如系统挂起、数据损坏或内部错误:Panic、Oops、BUG()、warning 等)使用 regzbot 追踪是被允许的。此外,如果某个 CI 系统发现的回归可能影响实际使用场景并会被用户注意到,也欢迎将其加入 regzbot 的追踪。
如何查看 regzbot 当前追踪了哪些回归?
查看 regzbot 的 Web 界面(linux-regtracking.leemhuis.info/regzbot/)即可获得当前被追踪的回归列表。另外,regzbot 通常会在每周日晚上(UTC)发送一次"Linux regressions report"(Linux 回归报告),这通常比 Linus 发布新的(预)版本早几个小时。
常见问题深度解析:判断一个情况是否属于回归
文档以问答形式澄清了大量边界情况,以下逐一解析。
真的所有回归都会被修复吗?
几乎全部都会被修复——前提是造成回归的变更(罪魁提交)被可靠地识别。有些回归无需罪魁提交也能修复,但通常识别罪魁提交是必须的。
升级软件就能避免的问题算回归吗?
几乎总是算。如果开发者告诉你这不算是回归,请按前述方式向回归追踪员咨询。
新内核更慢或更耗电,算回归吗?
算,但差异必须显著。例如微基准测试中 5% 的变慢不太可能被认定为回归,除非它也影响某个广泛基准测试超过 1% 的结果。有疑问时请咨询。
外部内核模块在升级后损坏,算回归吗?
不算。"不引入回归"规则针对的是内核向用户态提供的接口与服务,不涵盖外部开发的内核模块的构建或运行——这些模块运行在内核空间,通过偶尔会发生变化的内部接口挂钩内核。
安全修复导致的回归如何处理?
在极少数情况下,安全问题无法在不引起回归的前提下修复;此时安全修复优先,因为从长远看它是较小的恶。幸运的是,这种权衡几乎总能避免——受影响领域的关键开发者、往往还有 Linus 本人,都会非常努力地在不引起回归的情况下修复安全问题。
如果你确实遇到这种情况,先检查邮件列表归档,确认人们是否已尽力避免回归。如果没有,就报告它;有疑问时按前述方式咨询。
修复一个回归必然导致另一个回归怎么办?
这种情况确实会发生,但幸好不常发生。发生时,受影响代码领域的资深开发者应研究该问题,找到能避免回归或至少降低其影响的修复方案。如果你遇到此类情况,按照安全修复引发回归的流程处理:检查先前的讨论是否已有人尽力而为,有疑问时咨询。
预防之道:这类两难局面本可以避免——如果人们定期对每个开发周期的 mainline 预发布版本(如 v5.15-rc1 或 -rc3)进行一轮测试。设想某个在 v5.14 与 v5.15-rc1 之间合入的变更引起了回归,但它同时又是 5.15-rc1 某个改进的硬性前提。如果有人在 5.15 发布前发现并报告了它,所有这些变更通常可以直接回退、回归就此解决。但几天或几周后,这个解决方案可能就不可行了——因为某些软件可能已经开始依赖后续某个变更引入的方面,此时回退所有变更会对该软件用户造成新的回归,因此不可取。
数月前被移除的功能算回归吗?
算,但由于上一节所述原因,此类回归往往很难修复,需要逐案处理。这也是定期测试 mainline 预发布版本符合所有人利益的另一个原因。
似乎只有我一个人受影响,规则还适用吗?
适用,但仅限于实际使用场景:Linux 开发者希望保留移除只存在于阁楼和博物馆里的硬件支持的自由。另外请注意,有时回归无法避免——而进步是防止 Linux 停滞所必需的。因此,如果回归只影响极少数用户,出于更大的利益,可能符合他们和所有人的利益而让事情通过,尤其是存在某种简单的规避方法时(例如更新某些软件或使用为此专门创建的内核参数)。
回归规则适用于 staging 树中的代码吗?
不适用。根据 drivers/staging/Kconfig 中覆盖所有 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这会让内核的构建脚本以当前运行内核的配置文件(".config")作为将要编译的新配置的基础;随后所有新配置项被设置为其默认值,这应当会禁用那些可能引起回归的新特性。
用预编译的 vanilla 内核发现的回归可以报告吗?
可以,但前提是你必须确认新内核使用了与旧内核相似的配置文件(见上)——因为构建这些内核的人可能为新内核启用了某些已知不兼容的特性。如有疑问,请向内核提供方报告此事并寻求建议。
内核开发者的配套视角
本文聚焦用户视角,但了解开发侧的配套流程有助于理解整体机制,详见 Documentation/process/handling-regressions.rst:
- 子系统维护者负责落实规则,并受到树维护者的监督与支持——例如 mainline 的 Linus Torvalds,以及各 stable/longterm 系列的 Greg Kroah-Hartman 等人;
- 修复回归的补丁应使用
Closes:标签指向所有报告该问题的地方(regzbot 对Link:标签同样处理); - 应使用
Fixes:标签指明引起回归的提交; - 罪魁提交确定后,大多数回归的修复应在两周内合入 mainline,严重或影响面大的问题应在两三天内解决;开发者普遍被鼓励优先处理回归相关工作,并优先考虑直接回退罪魁提交这一最快速、最稳妥的修复方式。
结语
"不引入回归"是 Linux 内核开发的第一规则,但它并非空洞的口号,而是一套由规则、流程和工具共同支撑的完整体系:用户侧通过[REGRESSION]报告 + 抄送回归邮件列表 + regzbot 追踪,将问题送入官方处理队列;开发侧通过Closes:/Fixes:标签、优先修复与必要时回退,让绝大多数回归在两周内得到解决。作为用户,你只需要记住三件事:用相似配置对比新旧内核、按规范提交报告、让 regzbot 看到你的报告——剩下的交给这套运转了数十年的成熟机制。
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考