
尽管在 Linux 7.1 的合并窗口期间,已有大量令人关注的新功能和变更被合并,但截至目前,有两个提交请求(pull request)因被林纳斯·托瓦兹(Linus Torvalds)拒绝而尤为突出,并附带了他一贯直截了当的评论。
其中一个最初引起我兴趣的被拒提交,旨在解决在启用审计子系统(audit subsystem)时,现代高核心数工作站/服务器处理器上出现的性能退化问题。随着 CPU 核心数量的增加,审计框架(audit framework)可能会遇到性能瓶颈,而该提交正是试图解决这一问题。
克里斯蒂安·布劳纳(Christian Brauner)与红帽公司(Red Hat)的 Waiman Long 在提交请求中描述了这些补丁的作用:
“避免在 audit_context 初始化和重置路径时进行过多的 dput/dget 操作。
当审计子系统启用后,它会频繁调用 get_fs_pwd() 来获取对 fs->pwd 的引用,随后再通过 path_put() 释放这些引用。
在多个进程同时活跃地执行 open/close 系统调用、且处于同一工作目录的情况下,这种对引用计数的频繁修改会导致单个 pwd dentry 锁上的大量自旋锁争用(spinlock contention)。
尤其是在 CPU 数量较多的系统上——这种情况如今越来越普遍——与关闭审计子系统的情况相比,会造成明显的性能下降。为避免此类由审计机制引发的性能退化,我们新增了一组 fs_struct 辅助函数,以减少不必要的 path_get() 和 path_put() 调用,并修改审计代码以使用这些新辅助函数。”
尽管考虑到如今 CPU 核心数量日益增加、下一代处理器的核心数还将更高,这一改进具有重要意义,但林纳斯·托瓦兹(Linus Torvalds)对该设计并不满意。他回应道:
“我真的很不喜欢这个补丁,至少我会推迟合并它。
因为这在我看来真的很不对劲,感觉就像是一个‘黑科技’(hack)。
单看一些被修改的路径代码,比如copy_fs_struct函数中:path_get(&fs->root);这是为了增加 root 的引用计数,紧接着下一行却是:
get_fs_pwd_pool_locked(old, &fs->pwd);后者却以一种完全不同的方式复制了 pwd。
而 pwd 和 root 处理方式不同的唯一原因,是审计代码(audit code)对它们做了区别对待。
而这又是因为审计代码本身是历史遗留产物且存在缺陷,无法正确处理 chroot 环境。
pwd 和 root 路径本质上是同一枚硬币的两面,任何将它们区别对待的代码都是 错误的。
所以这个补丁实际上是把审计子系统的一个错误,暴露给了非审计用户。
我对此深恶痛绝。
……
[在思考了一些替代方案后]是的,是的,上面这些说法非常模糊,我也并没有亲自写代码,可能听起来像是一个疯子的胡言乱语。
我并没有深入思考这个问题。我只是看了一眼这个补丁系列,就有点反胃,然后试图想想‘也许我们可以用别的方法来做’,上面这些只是一个可能可行方案的粗略草稿。”
布劳纳随后回应表示,他同意托瓦兹的评估,即他自己也不喜欢那段代码,感觉像是一个“黑科技”(hack),并决定将其从提交请求中移除。
另一方面,另一个在 Linux 7.1 早期阶段惹恼林纳斯的提交请求涉及 RCU 代码。有人提出一个名为 BOOTPARAM_RCU_STALL_PANIC 的 Kconfig 选项,该选项允许在编译时默认启用“当 RCU 出现停滞时触发内核恐慌(kernel panic)”的功能。具体来说,如果启用了 BOOTPARAM_RCU_STALL_PANIC,那么 kernel.panic_on_rcu_stall 这个 sysctl 参数的默认值将被设为启用状态,从而在 RCU CPU 停滞时自动引发内核崩溃和重启。该功能的初衷是服务于高可用性系统,这类系统要求在检测到 CPU 停滞时能够自动恢复,而无需用户空间在启动时手动配置该 sysctl 可调参数。对此,托瓦兹回应道:
“不行。
天哪,别再做这些可怕的事情了。
我已经说过无数次了:内核配置阶段(kernel config phase)对于那些想要自己编译内核的新手来说,已经是最大的痛点之一,而我们 绝不应该 向人们提出 愚蠢的问题。如果有人想要这个功能,他们完全可以使用 sysctl,或者也许用某个内核命令行参数来实现,但我们 绝不能因此让其他所有人变得更糟。
我已经移除了这个令人作呕的 Kconfig 选项,并且我想明确告诉所有人:Kconfig 文件 不是你个人的游乐场。它们是面向 普通用户 最显眼的接口,我们希望鼓励这些用户去自己编译内核,从而参与到内核开发中来。
所以各位:下次当你忍不住想添加一个 Kconfig 选项时,请深呼吸一下,然后看看那个 Kconfig 文件,问问自己:‘也许我可以反过来移除那个 其他 没用的选项?’
让我们一起把内核变得更好,而不是更糟。”
在随后的讨论中也指出,通过在内核启动时使用形如 sysctl.kernel.panic_on_rcu_stall=true 的引导参数(boot parameter),已经可以轻松实现相同的行为。
转自 Linus Torvalds Rejects Performance Fix “Hack” & Kconfig “Terrible Things” For Linux 7.1 – Phoronix
Linuxeden开源社区