终于!“30 岁”的 Linux 内核 C 语言将升级到 C11

简介: 终于!“30 岁”的 Linux 内核 C 语言将升级到 C11

上周,Linux 内核邮件列表上关于“社区最近讨论了是否为内核采用现代 C 语言标准”的信息引发业内关注。刚刚,Linux 开源社区已正式宣布:内核 C 语言版本将在未来升级到 C11,且预计将在今年 5 月份的 5.18 版本之后生效。

image.png

这个突然的决定,也终于让拥有 30 年历史的 Linux 内核 C 语言迎来了升级。

众所周知,想要说服固执的 Linux 之父 Linus Torvalds 绝非易事。那么,这一次 Linus Torvalds 为何终于松口了呢?这里面,似乎还真有那么一点偶然因素。

事件起因还是要回到上周的那次的 Linux 社区讨论。

一条 Bug 引发的“连锁反应”

据悉,当时一位名叫 Jakob Koschel 的博士生正在研究与内核链表原语相关的推测性执行漏洞,过程中他发现了一个问题:Linux 内核广泛使用 struct list_head 定义的双链表:

image.png

struct list_head {

structlist_head *next, *prev;

};

通常,开发者通过将此类结构嵌入其他结构里的方式,来使任何相关的结构类型都可以创建链表。同时,该内核还提供了大量可用于遍历和操作链表的函数和宏。其中一个就是 list_for_each_entry(),这是一个伪装成控件结构的宏。

恰巧,问题出在了这个宏上。

我们假设该内核包含以下结构:

image.png

struct foo {

int fooness;

struct list_head list;

};

List 中的元素则可用于创建 foo 结构的双链接列表。

假设有一个名为 foo_list 的结构声明作为此类链表的头,则可以使用以下代码遍历此链表:

image.png

struct foo *iterator;

list_for_each_entry(iterator, &foo_list, list) {

do_something_with(iterator);

}

/ Should not use iterator here /

list 参数告诉宏 foo 结构中 list_head 结构的名称。对于迭代器指向的列表中的每个元素,该循环将执行一次。

而这样就会导致 USB 子系统中出现错误:在退出宏后,传递给该宏的迭代器仍可使用。当然,这是一件非常“危险”的事情。

image.png

所以,Koschel 提交了一个补丁,重新编写了有问题的代码,通过在循环结束后停止使用迭代器来修复这个错误。随后,Jakob Koschel 将(投机性安全列表迭代器建议)修复的与内核链接表相关的预测执行漏洞的补丁提交给了 Linus Torvalds。

Linux 之父终于被说服

最初,Linus Torvalds 本人似乎对这个补丁并不是很喜欢,也不知道该补丁与推测性执行漏洞有什么关系。但经过 Koschel 详细解释之后,Linus 承认了这只是一个常见的 Bug。

然而,事情并非那么简单,Linus 很快就意识到了真正的问题:传递给链表遍历宏的迭代器必须在循环本身之外的范围内声明。

而出现这种不可预测的错误的原因是 C89 中没有“在循环中声明变量”。

image.png

我们知道,虽然 Linux 内核正在快速发展,但它也依赖于一些非常古老的工具,其中之一就是其内核代码仍在使用 1989 年版的 C 语言标准,也就是说,该标准是在内核项目启动 30 多年前编写的。

像 list_for_each_entry()这样的宏,基本上总是将最后一个 HEAD 条目泄漏出循环,就是因为不能在循环本身中声明迭代器变量。

如果可以编写一个迭代器列表遍历宏来声明自己,那么迭代器在循环外就不可见,也不会出现这样的问题。

然而,由于内核停留在C89标准上,因此不可能在循环中声明变量。

因此,Linus 决定,“让我们升级一下”,也许是时候升级到 C99 标准了,尽管 C99 也有 20 多年的历史了,但它至少比 C89 更新一点,且可以在循环中声明变量。

既然 C89 已经过时了,为什么这么多年都没有改变呢?Linus 解释称,“这是因为我们在一些旧的 gcc 编译器版本上遇到了一些奇怪的问题,这些版本不能随意升级。”

然而,现在 Linux 内核已经将 gcc 的最低要求提高到了 5.1 版,过去那些奇怪的 Bug 应该消失了。

另一位核心开发者 Arnd Bergmann 也对此事比较关注,他认为可以升级到 C11 甚至更高版本,但升级到 C17 或 C2x 会破坏 gcc-5/6/7 支持,因此升级到 C11 更容易实现。

最终,Linus Torvalds 支持了这个想法,并宣布将“在 5.18 版合并窗口的早期尝试一下”。

虽然接下来转移到 C11 可能会导致一些意想不到的 Bug 也说不定,但如果一切顺利,下一个 Linux 内核版本将正式转移到 C11。您对此次升级事件有何看法呢?也欢迎在下方交流互动。

相关文章
|
7天前
|
安全 Linux 测试技术
Intel Linux 内核测试套件-LKVS介绍 | 龙蜥大讲堂104期
《Intel Linux内核测试套件-LKVS介绍》(龙蜥大讲堂104期)主要介绍了LKVS的定义、使用方法、测试范围、典型案例及其优势。LKVS是轻量级、低耦合且高代码覆盖率的测试工具,涵盖20多个硬件和内核属性,已开源并集成到多个社区CICD系统中。课程详细讲解了如何使用LKVS进行CPU、电源管理和安全特性(如TDX、CET)的测试,并展示了其在实际应用中的价值。
|
20天前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
68 15
|
1月前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
1月前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
1月前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
1月前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
1月前
|
负载均衡 算法 Linux
深入探索Linux内核调度机制:公平与效率的平衡####
本文旨在剖析Linux操作系统内核中的进程调度机制,特别是其如何通过CFS(完全公平调度器)算法实现多任务环境下资源分配的公平性与系统响应速度之间的微妙平衡。不同于传统摘要的概览性质,本文摘要将直接聚焦于CFS的核心原理、设计目标及面临的挑战,为读者揭开Linux高效调度的秘密。 ####
45 3
|
2月前
|
算法 Linux 调度
深入理解Linux内核调度器:从基础到优化####
本文旨在通过剖析Linux操作系统的心脏——内核调度器,为读者揭开其高效管理CPU资源的神秘面纱。不同于传统的摘要概述,本文将直接以一段精简代码片段作为引子,展示一个简化版的任务调度逻辑,随后逐步深入,详细探讨Linux内核调度器的工作原理、关键数据结构、调度算法演变以及性能调优策略,旨在为开发者与系统管理员提供一份实用的技术指南。 ####
97 4
|
2月前
|
缓存 并行计算 Linux
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
54 2
|
2月前
|
缓存 网络协议 Linux
深入探索Linux操作系统的内核优化策略####
本文旨在探讨Linux操作系统内核的优化方法,通过分析当前主流的几种内核优化技术,结合具体案例,阐述如何有效提升系统性能与稳定性。文章首先概述了Linux内核的基本结构,随后详细解析了内核优化的必要性及常用手段,包括编译优化、内核参数调整、内存管理优化等,最后通过实例展示了这些优化技巧在实际场景中的应用效果,为读者提供了一套实用的Linux内核优化指南。 ####
61 1