关注了就能看到更多这么棒的文章哦~
A disagreement over get_mm_exe_file()
By Jonathan Corbet
October 18, 2021
DeepL assisted translation
https://lwn.net/Articles/873066/
多年来,关于哪些内核符号(kernel symbol)应该被 export 到 loadable module 一直有不小的分歧。通常,这些分歧都是跟 proprietary module 可以获得那些哪些内核功能有关。但有时候其实是关于如何以最佳方式来解决一个问题的分歧。最近关于取消 core kernel 的一个功能的 export 的讨论就是一个例子。
众所周知,loadable module 是在系统启动后被加载到 core kernel 中的大块内核代码。大多数 module 是设备驱动,但令人惊讶的是,有许多内核功能可以编译成 module 的形式。内核中的代码可以随意直接使用通常的 C 语言范围规则能访问到的 symbol,而 loadable module 则受到更多的限制,它们只能使用那些被明确 export 出来的 symbol。在理论上,export 出来的 symbol 接口是受到严格管制的。在实践中,多年来有数以万计的 symbol 被 export,并没有受到很多监督限制。事实上,当一个 module 开发者想要使用一个 core kernel 开发者不希望 export 的 symbol 时,社区仍然偶尔会出现争议。
AMD GPU 开发者最近遇到了一个问题。虽然许多用户空间的图形代码(user-space graphics code)早已开始转向来使用 atomic mode-setting API 了,但似乎 Chrome OS 目前只是部分实现了这一转换工作。如果混合着来使用新、旧两种 API,Chrome OS 可能会碰到硬件无法配合它的问题。为了防止这种情况发生,amdgpu 驱动就限制了所有客户端使用 overlay。Simon Ser 的相关邮件更详细地描述了这种情况,而且无疑比编者的描述更精确。
这种限制可以使 Chrome OS 能能够工作,但是这种做法也不必要地对其他那些没有混用 API 的客户端施加了限制。为了解决这个问题,Ser 添加了一个 patch,希望调用 get_mm_exe_file() 来获取用户空间正在运行的程序的名称。如果(也只有在)这个名字是 chrome 的情况下,才会强制限制对 overlay 的使用。这使得 Chrome OS 能够继续以其习惯的方式工作的同时,又给了其他客户端更多的自由。
Ser 不知道的是,今年 9 月份的时候 Christoph Hellwig 就删除了这个函数的 export,使得其无法用在 loadable module 中了。一旦 Ser 的补丁进入 linux-next,那么由于它引用了一个不再被 export 的 symbol,这当然会导致 build 出错。linux-next 的维护者 Stephen Rothwell 就把这个编译错误报告给了相关维护者。于是,Ser 才意识到他的改法无法在 mainline kernel 中正常工作。
Ser 的第一个反应是询问 get_mm_exe_file() 是否可以再次被 export 出来,因为 amdgpu 驱动现在在使用它了。Hellwig 明确表示不愿意这样做。在那封邮件以及随后的邮件中,Hellwig 的解释并不是很礼貌,甚至在 Ser 要求改变语气后也仍是保持原样。先不考虑这个交流方式的问题,这里其实还是有一个观点需要大家正视。
为什么内核不应该 export get_mm_exe_file()?Hellwig 的观点是,内核代码不应该根据在用户空间运行的程序的名字来改变其行为。这个名字完全在用户空间的控制之下,无论是出于恶意的原因,还是只是在正常的开发过程中,它都可能在任何时候随意改名。除此之外,我们假设 Chrome OS 最终会被 fix,不再以这种方式来混合使用 API,届时 amdgpu 驱动中的检查就不再有必要,而且可能确实有害。不过,我们没有办法知道这个检查什么时候可以被取消。因此,这个基于当前运行程序名称的特殊检测可能会存在很长时间,远远超过它真正有用的时间。
但问题是,改变 amdgpu 驱动的行为将破坏现有的 Chrome OS 系统。根据 Hellwig 的说法,正确的解决方案是要求用户空间来明确选择那种不受限制的行为方式。Chrome OS 不会采取这种选择,它就还可以继续正常工作。绝大多数的活跃的应用程序都可以要求申请取消限制。Ser 不喜欢这个解决方案。"不,我们不能对每一个 uAPI 的滥用都有一个'I_AM_NOT_BROKEN' 的 ioctl。用户空间检测已经确定是这里最好的行动方案了"。Hellwig 坚持认为,如果一个 API 的改动破坏了用户空间,唯一正确的解决方案是准备一个新的函数调用来启用这个新的行为。
10 月 14 日,Ser 把 amdgpu tree 中的相关 patch 都 revert 掉了。不过,似乎也没有提供一个单独的 API 调用,相反,原来的 patch 看起来将只会是在 Chrome OS 的 kernel 中合入。这也是解决这个问题的一个合理方案。Chrome OS 的开发者会知道他们什么时候可以放弃这个 patch,同时,它也不会使 mainline kernel 变得混乱。
这个小插曲展示了对 module 的 export symbol 的控制是如何被用来限制这些 module 可以做什么的,也希望能够借此来提高整个内核代码库的质量。在这次的情况下,最终的结果看起来是朝着正确的方向发展的,尽管通往这个解决方案的道路不那么愉快,这是不必要的。多年来,内核项目在维护技术标准和尊重开发者方面已经有了提高,但显然在这两方面都还有进步空间。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~