Jonathan Corbet, Gemini translation
原文链接:https://lwn.net/Articles/1058041
对于操作系统内核而言,瞬态设备(transient devices) 的处理一直是个棘手难题。它们可能在任何时候突然从系统中消失,但内核中指向它们的数据结构却可能依然被某些代码引用着。多年来,如何妥善管理这种资源生命周期的不确定性,一直困扰着内核开发人员。
2025年9月,Tzung-Bi Shih 提交了一系列关于可撤销资源管理(revocable resource-management) 的补丁,似乎为解决这个问题提供了一条路径。然而,在此之后,新的问题浮现出来,导致原计划将该系列补丁合入 Linux 7.0 主线的工作被叫停。
核心思路:用SRCU管理短期引用
这套补丁的核心思想,在于精细管理与瞬态设备关联的数据结构引用。任何需要访问此类数据结构的内核代码,都必须先尝试获取一个短期引用。如果设备依然存在且功能正常,这次尝试就会成功。这个引用受到可睡眠的读-复制-更新(SRCU) 机制的保护,确保相关的数据结构在下一个SRCU宽限期结束前不会被释放。
一旦设备从系统中移除,对应的驱动程序会将其标记为“已离开(gone)”,并拒绝之后所有获取其数据结构引用的请求。等到SRCU宽限期结束后,数据结构的所有者就能确信不再有代码持有对其的引用,从而可以安全地释放内存。这样一来,数据生命周期的不确定性就被一个明确的“何时不再使用”的信号所取代。
从欢迎到质疑:合并之路的波折
补丁系列发布时,Greg Kroah-Hartman 表示了欢迎,并将其纳入了驱动核心仓库,打算在7.0合并窗口期间推送至上游。但到了2026年1月24日,情况急转直下。Johan Hovold 请求撤回(revert)这个补丁系列,他抱怨称这套代码本就不应该被应用。通常,像这类基础设施性质的代码在没有实际用户的情况下是不会被接受的,但这次显然是个例外——内核树中并没有使用这个可撤销访问功能的代码。
Hovold 批评道,该功能拟议的使用场景其实并不真正需要它,而且代码本身还存在一些严重的竞态条件漏洞。他认为,可撤销代码应该被撤回,“直到提出并正确评估了重新设计方案”。
Kroah-Hartman 最初抵制了撤回的想法:
啊,但我确实认为这是前进的方向,因为这种模式/想法在内核的Rust侧是行得通的,而且这正是我多年来一直要求的:)
但是,是的,如果没有真正的用户,我很难证明其合理性。但是,我希望它现在就存在于树中,以便许多其他人可以轻松地尝试它。如果事实证明它不正确且无法正常工作,那么好,我们将彻底删除这些文件。但我还不确定我们是否已经到了那一步。
他所指的,是内核中Rust代码使用的 Revocable trait。这个抽象(无运行时开销地)保证了其所有者所指向的数据结构不会突然消失。对于那些无法做出此类保证的场景,则有一个 try_access() 函数,其工作方式与此次提出的C语言实现非常相似。Danilo Krummrich 详细描述了Rust的实现,并指出由于“语言限制”,C语言的实现无法以完全相同的方式工作,但他认为可撤销补丁系列是探索如何将Rust模式应用到C侧的一次有价值的尝试。
设计哲学之争:安全抽象 vs. 代码异味
然而,Jason Gunthorpe 将这种机制——以及任何允许在设备注销后仍能访问其数据结构的接口——描述为“危险的”。他认为使用 try_access() 函数应该被视为一种“代码异味(code smell)”,表明驱动程序或子系统中存在值得怀疑的设计。
Gunthorpe 指出,Rust抽象的真正价值在于它能强制记录哪些上下文可以安全地访问设备结构,而哪些是不确定的。相反,C语言版本迫使所有访问都被视为不确定的,这丧失了文档价值,损害了性能,还可能引入其他类型的错误。
Hovold 将 Revocable 描述为“一种可能在Rust中需要,但在其他地方不一定需要的设计模式”。Gunthorpe 的态度则更为强硬,他认为添加类似Rust抽象的东西“不是我们想要做的”。他主张应该修改设计,确保驱动程序的操作(通常因为聚集在 file_operations 结构体中而被称为“fops”)只在资源不会从下方被抽走的安全上下文中运行。Laurent Pinchart 对此表示赞同,并勾勒了一个围绕更安全的 file_operations 调用的可能解决方案。
撤回与未来:一次失败的合并尝试
与此同时,补丁作者Shih自然反对撤回。他表示,至少将代码保留在 linux-next 测试分支中会有所帮助,并随后发布了另一个独立的补丁系列,修复了Hovold报告的竞态条件。Kroah-Hartman 迅速采纳了这些修复,但这又引来了Hovold的又一次抱怨,他再次要求撤回整个系列。
作为回应,Kroah-Hartman 为他接受修复补丁的行为进行了辩护,但同意在7.0发布周期中,从构建中禁用可撤销功能。然而这并未平息争论,Hovold回应说:“API设计不应该在树内以增量方式进行”。
几天后的2月6日,Kroah-Hartman 最终选择了让步,应用了Hovold的撤回补丁。“内核开发人员/维护者一年只‘被允许’进行一次重大争论/斗争,我真的不想在今年这么早的时候就耗尽我2026年的额度:)”他要求Shih仔细研究反馈,准备一个新的补丁系列重新评审,或许未来能合入某个内核版本。
当然,为内核(或任何自由软件项目)提出改进时,没有人希望看到这样的结果。但这种情况确实时有发生。如果一切顺利,这次的挫折最终可能会催生出一个更好、更易于维护的解决方案,从而真正解决那个困扰内核开发者多年的老问题。
社区讨论摘要
本文的讨论也反映了内核社区对设计哲学的不同见解。一方认为借鉴Rust的撤销机制能解决生命周期难题,另一方则坚持应通过更严谨的上下文设计来根治问题。虽然此次尝试暂告段落,但辩论过程有助于形成更清晰的技术共识。像这样的深度技术探讨,正是像云栈社区这样的开发者平台所珍视的,它推动了知识的沉淀与理念的碰撞。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。