diff -u:复杂化 printk()
内核开发的新内容:复杂化 printk()。
这太简单了!内核决定输出一条日志消息,因此它调用 printk() 将消息发送到串行控制台——但事实并非如此简单。如果内核正处于崩溃之中,而日志消息是诊断问题所需的关键线索怎么办?当您不知道可以依赖系统的哪些部分时,您如何输出日志消息?如果系统内存不足或陷入原子上下文中,无法从任何崩溃的地方切换到执行 printk() 的代码怎么办?
用户代码在生成输出时可以安全地忽略各种极端情况,但当内核生成输出时,正确处理这些情况至关重要。
更糟糕的是,这些极端情况往往以难以重现的方式发生,从而可能引发关于错误是否存在的争议。您如何重现导致日志记录系统本身无法告诉您发生了什么的错误?
一场持续多年的辩论最近再次出现在内核邮件列表中,Sergey Senozhatsky 发布了一个补丁,以修复他和其公司数据中心的其他人员一直在看到的系统崩溃。不幸的是,他的解决方案给已经很复杂的 printk() 代码增加了许多复杂性,并且它修复的错误无法按需重现。
Steven Rostedt 有一个单独的 printk() 补丁,也非常复杂,但比 Sergey 的补丁简单得多。唯一的问题是,它没有解决 Sergey 试图修复的问题。因此,大部分电子邮件线程都是 Sergey 和其他人试图说服 Steven 和其他人相信该错误是真实存在的。他们发布了进程跟踪和逻辑路径,但 Steven 始终没有被说服。特别是,在 Sergey 方面能够证明实际问题的案例中,Steven 反驳说,用例完全不切实际——例如,当单个 CPU 完成所有工作,而系统上的所有其他 CPU 仍然处于空闲状态时。
与此同时,相当多的人只是想将 Steven 的代码推送到主线内核源代码中,看看会发生什么。也许 Sergey 的系统崩溃会停止?但是,像这样将某些东西扔到野外绝不是一个有吸引力的选择,并且这似乎源于这样一个事实,即很难知道当事情出错时 printk() 实际上在做什么。
讨论期间绝对没有结论。多年的辩论仍然是多年的辩论。然而,可能已经朝着某个方向或另一个方向有了一点推动,因为 Steven 已经开始觉得 Sergey 试图修复的系统崩溃实际上可能是真实的,但由其他原因引起的,并且他已经开始与 Sergey 合作尝试诊断这一点。
这一切都非常有趣,因为即使开发人员在这种情况下彼此之间经历了很多挫折,他们仍然保持合作,试图找到解决问题的方法。无法确定最终结果如何。也许有人会找到一种方法将整个 printk() 代码分解成一堆更小但更简单的元素,以便可以重现和分析错误,而不是仍然难以解决。