Linux 内核新闻 - 2013年7月

作者:Shuah Khan

Linux 内核社区正忙于集成和测试 3.11 内容,进行 3.12 开发,并最终确定即将于 2013 年 10 月 21 日至 23 日在英国爱丁堡举行的 Linux 欧洲会议和内核峰会的主题议程。让我们从发布新闻开始。

主线发布(Linus 的树)新闻

自从我的上次报告以来,3.10 已经发布,3.11 现在处于 3.11-rc3 阶段。进入 3.11-rc2 的 ACPI 背光更改导致了回归,并在本次 rc 中被还原。我将在本文后面详细介绍背光更改的性质。crc t10 dif 加密支持已被还原,因为此更改存在 initrd 基础设施问题。

有关此 rc 的更多信息,请参阅 Linus 的 3.11-rc3 发行说明: https://lkml.org/lkml/2013/7/29/16

Linus 说 rc3 的提交次数比 rc2 多 50%。幽默地说,Linus 认为,提交次数的增加部分原因是由于他指示人们结束茶水间的谈话,回到工作岗位。现在,在收到比 rc-2 多 50% 的提交后,他要求人们享受夏天并休息一下。Linus 只要求修复回归错误。我们只需拭目以待,看看下一个 rc 的提交次数是否会减少。

稳定版本新闻

    截至本文撰写之时

  • 当前最新的稳定版本是 3.10.4。
  • 之前的稳定版本是 3.9.11,现在已是 EOL。此稳定分支将不再有更新。
  • 长期稳定版本是 3.0.88、3.2.49 和 3.4.55。
  • 扩展稳定版本是 3.8.13.5 和 3.5.7.17。
  • 2.6.y 的长期版本是 2.6.34.14 和 2.6.31.61。
  • Linux RT 稳定版本是 3.0.85-rt113、3.2.48-rt69、3.6.11.6-rt38 和 3.4.52-rt67。

ACPI 背光更改

Windows 8 不使用 ACPI 来控制背光,而是将背光控制留给各个图形驱动程序。然而,并非所有图形驱动程序都具有背光控制功能。除了驱动程序缺少背光控制之外,当操作系统通过标准的 ACPI _OSI 方法告诉 BIOS 它支持 Windows 8 时,背光在某些平台上也无法正常工作。您可能想知道,如果 Windows 8 不再使用 ACPI 来控制背光,为什么 Linux 内核还要关心。原因并非那么简单,下面解释了原因。

ACPI _OSI 方法的定义是为了让操作系统可以调用此方法来告知平台 BIOS 其可以支持的功能。然而,平台 BIOS 开始使用此方法来查询操作系统标识,而不是使用为查询操作系统标识而定义的 _OS 方法。在某些平台上,平台 BIOS 在通过 _OSI 方法查询操作系统标识后,会动态调整固件功能,并应用针对特定操作系统的已知操作系统错误(如果有)的解决方法。

当 BIOS 使用 _OSI 方法查询操作系统标识时,Linux 内核不会将自身标识为 Linux。不将自身标识为 Linux 的意图和理由是消除供应商平台 BIOS 代码中 Linux 特殊处理案例的扩散。供应商特殊处理代码可能会导致 Linux 内核错误和性能问题,尤其是在 Linux 可以在内核中更好地处理某个功能,而 BIOS 却使用其自身的次优实现来覆盖它时。本质上,特定于操作系统的供应商代码会在操作系统和平台之间引入关联,这种关联基于可能不正确和/或随着操作系统功能的不断发展而不再有效的假设。消除此类特殊关联将导致两端的维护模型更简单。

有关 Linux 支持的 _OSI 字符串的更多信息,请参阅 drivers/acpi/acpica/utosi.c 中定义的 struct acpi_interface_info acpi_default_supported_interfaces。

有了这些背景知识,现在让我们讨论一下为什么 Linux 关心 Windows 8 背光控制状态。Windows 8 要求平台运行 Windows 8 的最低背光支持级别,例如,至少 101 个不同的亮度控制级别。在 Linux 3.7 中,Linux 内核开始响应 BIOS 对 Windows 8 的 _OSI 查询返回 true,以使 BIOS 在平台上启用增强的 Windows 8 所需的背光功能。好处是现在平台具有增强的背光功能。然而,这导致了与驱动程序中缺少背光支持以及平台背光实现损坏相关的问题浮出水面,导致 Linux 内核中的背光支持不稳定。

在这些平台上禁用(不注册)ACPI 背光接口听起来像是一个显而易见的简单解决方案,但这并非在所有情况下都有效。例如,在具有良好工作的 ACPI 背光接口和可以控制背光功能的图形驱动程序的平台上禁用 ACPI 背光接口是不明智的,因为它会无缘无故地关闭一项功能。另一方面,是一个具有损坏的 ACPI 背光接口和平台供应商背光驱动程序也损坏的平台。在第二种情况下,如果内核不注册背光接口,平台将注册其自身损坏的背光驱动程序。这是另一种同样糟糕的情况。

一组补丁已进入 Linux 3.11-rc2,以解决特定于 Intel i915 图形驱动程序的这些 ACPI 背光问题。这些补丁更改内核以注册 ACPI 背光接口,直到 i915 加载,然后当固件调用 _OSI 检查 Windows 8 标识时,驱动程序将注销该接口。此修复解决了前面讨论的两种情况。当平台具有工作的 ACPI 背光接口和实现背光控制的图形驱动程序时,注册 ACPI 背光接口可确保该功能保持启用状态。在具有工作 ACPI 背光接口和 1915 驱动程序的平台上,当驱动程序加载时,ACPI 背光接口将被注销,从而解决了在使用 i915 时禁用接口的需求。尽早注册 ACPI 背光接口可确保损坏的供应商背光驱动程序不会被 BIOS 注册。

然而,由于此补丁集引入了回归,因此已在 Linux 3.11-rc3 中还原,并且正在进行解决回归的工作。预计在以后的 3.11-rc 中可能会出现一个没有回归且可以解决原始问题的未来提交。

有关问题和补丁集的更多信息,请参阅:http://permalink.gmane.org/gmane.linux.kernel.commits.head/396675

当补丁添加新文件时,如何要求 git 跟踪它们?

最近关于在应用稳定版本补丁后需要删除未跟踪文件的讨论,导致了来自几位维护人员和 git 作者 Linus 本人关于处理添加新文件的补丁的几个很好的技巧。当补丁添加一个新文件,并且如果它通过“patch -p1 < ../file.patch”作为补丁文件应用时,git 不知道新文件,它们将被视为未跟踪文件。“git diff”不会在其输出中显示这些文件,“git status”会将这些文件显示为未跟踪文件。在大多数情况下,构建和安装内核等都没有问题,但是,“git reset --hard”不会删除新添加的文件,随后的 git pull 将会失败。以下是告诉 git 关于新文件并让它跟踪它们以避免上述问题的几种方法

选项 1:在应用添加新文件的补丁后,运行“git clean”以删除未跟踪文件。例如,git clean -dfx 将强制删除未跟踪的目录和文件,忽略 .gitignore 文件中指定的任何标准忽略规则。您可以包含 -q 选项以在安静模式下运行 git clean,如果您不关心知道哪些文件被删除。

选项 2:另一种方法是通过运行“git apply --index file.patch”来告诉 git 跟踪新添加的文件。这将导致 git 应用补丁并将结果添加到索引。完成此操作后,git diff 将在其输出中显示新添加的文件,git status 将正确报告状态,将这些文件标记为新创建的文件。

就我而言,我喜欢第二种选择,并计划从现在开始使用它而不是 patch 命令来应用稳定版本补丁。

请在 https://lkml.org/lkml/2013/7/24/488 找到关于此主题的讨论。

关于如何实现良好的跟踪点代码的提示

我最近发送以供审查的跟踪点补丁引发了关于最佳实践和跟踪点作者兼维护者 Steve Rostedt 关于跟踪点实现的技巧的讨论。我正在分享我所学到的知识,以帮助其他开始向内核代码添加新跟踪点的人。

跟踪点使用跳转标签,这基本上是对分支的代码修改。

 

 [ code ] nop back: [ code ] return;  tracepoint: [ tracepoint code ] jmp back; 

当我们启用跟踪点时,代码被修改为

 [ code ] jmp tracepoint [ code ]  tracepoint: [ tracepoint code ] jmp back; 

这很聪明,应该导致跟踪点代码在跟踪点处于禁用状态时不会增加任何开销。然而,在某些情况下,gcc 在其优化中会感到困惑,并将跟踪点参数处理工作推送到即使在禁用跟踪点时也会运行的代码部分。因此,这个故事的寓意是,通常更好的做法是在 TRACE_EVENT() 宏中尽可能多地实现跟踪点工作。

例如

代替

 trace_event_example(dev_name(dev), dev_driver_string(dev),     dev->parent ? dev_name(dev->parent) : "none"); 

实现

 trace_event_example(dev);  And in the TRACE_EVENT() macro:  TP_fast_assign(  const char *tmp = dev->parent ? dev_name(dev->parent) : "none";  const char *tmp_i = pm_ops ? pm_ops : "none ";  __assign_str(device, dev_name(dev));  __assign_str(driver, dev_driver_string(dev));  __assign_str(parent, tmp); 

您可以看到在好的示例中如何在宏中完成参数处理。如有疑问,比较在 TRACE_EVENT() 宏外部执行工作的跟踪点代码的 .s 输出与在 TRACE_EVENT 宏内部执行工作的跟踪点代码的 .s 输出,可以向您展示优化方面的差异。

最后的想法

正如您可能已经观察到的,自我的上次报告以来,在强调质量胜于新功能且没有回归的情况下,另一个 Linux 版本取得了稳步进展。如果需要还原功能来实现质量目标,那么最终结果是好的。

加载 Disqus 评论