Linux 内核开发者对 Rust 进入内核的讨论
Rust 内核
![](/data/attachment/album/202209/29/154314iu7gayl7j877guo7.jpg)


Rust for Linux 这个项目是希望今后可以使用 Rust 编程语言来编写内核代码，该项目已经进行了几年，有越来越多的开发者认为是时候将这项工作合并到主线中了。在 2022 年的 Linux 内核维护者峰会上，Miguel Ojeda 向大家更新了此项目的最新状况，希望能达成一致来确定何时可以完成合并。


他得到的答案是很清晰的：**内核中确实很快会有 Rust 了。**


这方面并没有什么悬念。Linus Torvalds 在会议开始时就说，**他计划接受（可能在 12 月中旬发布的） 6.1 内核的 Rust 补丁，除非他听到强烈的反对意见。**Ojeda 表示，他很期待这一天，并询问这些补丁应该如何进入主线。Torvalds 说，他不愿意直接接受这些补丁，所以看起来很可能需要 Kees Cook 来将这项工作引向上游。


Dave Airlie 说，有一些 MacBook 驱动程序的开发者打算用 Rust 来做他们的工作，所以很可能在不久之后就会有真正的 Rust 驱动程序进入上游了。不过，Torvalds 说他希望最开始只合入尽量少的内容，只是让基础设施先进入内核，让开发者开始使用它。它应该可以完成编译，但应该**基本仅限在 “hello, world” 这种水平**就好。他说，这将是一个向世界发出的信号：“终于落地了”。


Greg Kroah-Hartman 问道，针对特定子系统的 Rust 绑定实现，该如何进入上游；是应该通过 Rust 树还是通过相关子系统的维护者？Ojeda 回答说，Rust 核心支持应该通过 Rust 树来合入，但其他的应该经过维护者来合入。Alexei Starovoitov 担心，如果子系统维护者不想在他们的子系统中使用 Rust，他们也无法拒绝 Rust 补丁；James Bottomley 补充说，对于长期从事 C 语言开发的人来说，Rust 可能是一种很难理解的语言，把它强加给维护者并不合适。Torvalds 回答说，这应该由维护者决定；目前没有必要制定统一的规则。


Paolo Bonzini 说，对于不熟悉该语言的开发者来说，针对特定子系统实现抽象层的 Rust 代码往往是最难读懂的，“but it's stupid code”，并没有做什么复杂的动作。驱动程序级的 Rust 代码则要简单易懂得多。Torvalds 重申，就目前而言，维护者将可以说他们不想接受 Rust。但 Starovoitov 反驳说，无论他如何决定，BPF 都会受到影响；开发者需要能够对 Rust 代码进行跟踪 来调试问题。他补充说，**每个人最终都会需要了解 Rust**。Torvalds 回答说，他预计这个过程需要几年时间。


Cook 说，这种变化将类似于内核所经历的许多 C 语言变动。停止使用可变长度数组也是一个类似的过程，开发人员目前已经习惯了这一点。Torvalds 说，这其实更加类似于 BPF 的引入过程；这也是一种新的语言，起初是针对特定使用场景的，但现在已经无处不在了。


Ted Ts'o 指出，内核必须使用不稳定的 Rust 功能，这就导致不好确定应该使用 Rust 的哪个版本了。也许开发者应该宣布一个特定版本的编译器作为内核开发所使用的版本？这将鼓励发行版提供商把这个版本打包发行出来，使其得以更广泛地被采用。Thomas Gleixner 说，在 kernel.org 上提供我们选定的编译器应该就够了，但 Torvalds 回答说，只要有可能，他都希望**优先从发行版提供商那里获取编译器**。Bottomley 问道，Rust 什么时候会成为内核编译的必备条件；答案是 “当某人需要使用的硬件需要 Rust 的时候”。Torvalds 说，如果这一天到来了，那说明 Rust 在内核开发领域是非常成功的了。


Gleixner 问 Rust 语言现在的规范性如何；Ojeda 回答说，这取决于人们希望用什么。Rust 保证了稳定功能都可以向后兼容，所以这些功能不会意外不能用了。不过，内核正在使用一些不稳定的功能；这些功能出现变动是很有可能的。目前正在做的工作就是把这些功能稳定下来，以便让内核能够稳定地使用它们。


目前正在努力为 Rust 编写一个强调安全的系统的规范，这会最终得到一个类似于标准的文档。不过 Ojeda 说目前基于 GCC 的 gccrs Rust 编译器的开发者发现当前的文档有些地方比较模糊。其中经常把相关行为定义为 “参考 rustc 编译器的实现方式”。他说，这 “不是好事”，但会继续改善。


Gleixner 还询问了生成 Rust 绑定的工具，尤其是有没有自动化工具来确保 Rust 和 C 版本的数据结构是相互匹配的。Ojeda 说，这些工具确实存在，但它们还不能成功地对所有类型完成自动转换。这也是可以解决的。


最后，Gleixner 告诫 Rust 开发者**不要改变 C 语言中锁定原语的语义**；目前看来大家也没有表现出这样的倾向。Ts'o 补充说，应该从一开始就让 Rust 的锁定抽象能跟 lockdep 这个锁定检查工具配合起来。Chris Mason 插话说，如果 Rust 代码需要 lockdep，这将是该语言成功的另一个标志，是时候 “跳个舞庆祝胜利” 了。


人们经常说，将 Rust 合并到内核代码树中还是一个实验性质的动作；如果不成功就可以删除掉。Ojeda 说，为 Rust for Linux 工作的开发者们**想知道试验期可能会有多长**。不过，他并没有从这个小组讨论中得到切实的答案。


相反，Bottomley 建议说，与其引入 Rust，不如直接**将更多类似 Rust 的功能移入 C 语言**。Ojeda 说，他实际上一直在与 C 语言委员会合作来推动这些改进，但这方面的任何变动如果能够落实，也需要很长的时间。Christoph Hellwig 说，**除非计划用 Rust 重写整个内核，否则这种改动无论如何都得去做**；他对使用一种新的语言来重写已经能正常工作的代码的方案不是很满意。他说，也许 sparse 静态分析工具可以加强一下，从而实现更多 Rust 可以做到的检查。Ojeda 回答说，这种做法最终的效果就像是又获得了一个 Rust 一样——但时间上要晚很多。


Hellwig 继续说，可以随着时间的推移，来逐步采用类似 Rust 的一些功能。这 “**必定是不如从 Rust 开始**”，但内核社区现在有一个庞大的代码库需要管理。他说，需要有一种方法将类似 Rust 的语言的好处纳入所有的 C 代码中。Cook 说他一直在推动编译器开发人员来创建更安全的 C 语言。


Ts'o 在会议结束时指出，语言设计本身就是一个耗时很长的研究项目；也许我们大家应该在下一年来专注于策略问题。Torvalds 说，他希望看到各位维护者能运行一些持续集成测试并且加入 Rust 相关的测试——这个情况其实已经在进行中了。Laurent Pinchart 说，Rust 开发者需要准备好前期需要给内核社区提供支持；开发者会很快掌握一些技能，在一段时间后应该可以开始相互帮助了。Torvalds 补充说，Rust 其实并不是那么可怕的；“**毕竟不是 Perl**”。


当被问及文档问题时，Ojeda 说，Rust 的开发者正试图改进一些相应的 C 语言中已经完成了的文档。例如，可以让 Rust 的文档机制能很简单地就确保这些例子是可以被实际测试通过的。他们正在遵守关于应如何解释不安全区块的规则。


时间不够了，Matthew Wilcox 最后问道，内核开发人员是否应该编写地道的 Rust 代码，还是说应该写 “C in Rust”。Ojeda 回答说，**这些代码在开始时可能更像 C 语言**；采用更高级的功能（如 async）可能会需要更长时间。Gleixner 问，怎样才能防止开发者使用那些不稳定的特性（是说等内核使用的特性已经变成稳定特性之后）；答案是指定内核开发时使用的编译器版本。


OK
# Next steps for Rust in the kernel

The Rust for Linux project, which is working to make it possible to write kernel code in the Rust programming language, has been underway for a few years, and there is a growing number of developers who feel that it is time to merge this work into the mainline. At the 2022 Linux Kernel Maintainers Summit, Miguel Ojeda updated the group on the status of the project with the goal of reaching a conclusion on when this merge might happen. The answer that came back was clear enough: Rust in the kernel will be happening soon indeed.This article brought to you by LWN subscribersSubscribers to LWN.net made this article — and everything that surrounds it — possible. If you appreciate our content, please

[buy a subscription]and make the next set of articles possible.

There was little suspense on that front; Linus Torvalds spoke up at the beginning of the session to say that he plans to accept the Rust patches for the 6.1 kernel (likely to be released in mid-December) unless he hears strong objections. Ojeda indicated that he would like to see that happen and asked how the patches should be routed into the mainline. Torvalds said that he would rather not accept them directly, so it seems likely that Kees Cook will be routing this work upstream.

Dave Airlie said that there are MacBook driver developers who are intent on
doing their work in Rust, so there will likely be real Rust drivers heading
upstream before too long. Initially, though, Torvalds said that he would
like to see a minimal merge just to get the infrastructure into the kernel
and allow developers to start playing with it. It should build, but
shouldn't do much of anything beyond the "hello, world" stage. That, he
said, will be a signal to the world that "it's finally happening".

Greg Kroah-Hartman asked how subsystem-specific Rust bindings will go upstream; will they go through the Rust tree or via the relevant subsystem maintainers? Ojeda answered that core Rust support will go through the Rust tree, but the rest should go through maintainers. Alexei Starovoitov worried that subsystem maintainers would not be able to refuse Rust patches even if they do not want to see Rust used in their subsystems; James Bottomley added that Rust can be a hard language for longtime C developers to understand, and that it would not be good to force it on maintainers. Torvalds answered that it should be up to the maintainers; there is no need for global rules at this point.

Paolo Bonzini said that the Rust code implementing abstractions for subsystems is often the most unreadable for developers who are unfamiliar with the language, "but it's stupid code" that is not doing anything complex. Driver-level Rust code is a lot more straightforward. Torvalds repeated that, for now, maintainers will be able to say that they don't want to deal with Rust. Starovoitov countered, though, that BPF will be affected regardless of what he might decide; developers will need to be able to trace Rust code to debug problems. Everybody will need to know Rust eventually, he added. Torvalds replied that he expects that process to take years.

Cook said that this change will be similar to many of the C language changes that the kernel has gone through. The switch away from variable-length arrays was a similar process, and developers have gotten used to it. Torvalds said that it's closer to the introduction of BPF instead; it's a new language that was initially targeted at specific use cases, but which is now everywhere.

Ted Ts'o noted that the kernel has to use unstable Rust features, and that creates uncertainty about which version of the language should be used. Perhaps the developers should declare a specific version of the compiler as the one to use for kernel development? That would encourage distributors to package that version, making it more widely available. Thomas Gleixner said that having the blessed compiler available on kernel.org would be good enough, but Torvalds answered that he would rather get compilers from his distributor if possible. Bottomley asked when Rust would become mandatory to build the kernel; the answer was "when the hardware he has requires it". Torvalds said that, if and when that point comes, it will be an indication that Rust is a success for kernel development.

Gleixner asked about how well specified the Rust language is now; Ojeda
answered that it depends on what one is looking for. Rust guarantees
backward compatibility for stable features, so those will not break in
surprising ways. The kernel, though, is using a number of *unstable*
features; those features are, unsurprisingly, unstable. Work is being done to
stabilize those features so that the kernel will be able to count on them
going forward.

There is currently an ongoing effort to write a specification for Rust for safety-critical systems that will lead to a standard-like document. At the moment, though, Ojeda said, the developers of the GCC-based gccrs Rust compiler are finding the current documentation to be vague at times. Often, behavior is specified as "whatever the rustc compiler does". That is "not good", he said, but there is a path forward.

Gleixner also inquired into the tools that are generating the Rust bindings and, specifically, whether there is automation to ensure that the Rust and C versions of data structures match each other. Those tools do exist, Ojeda said, but they do not yet automatically convert all types successfully. That can be fixed.

Finally, Gleixner admonished the Rust developers to not change the semantics of any C locking primitives; it's worth noting that they have shown no inclination to do that so far. Ts'o added that Rust's locking abstractions should be made to work with the lockdep locking checker from the beginning. Chris Mason interjected that, if lockdep is needed for Rust code, that will be another sign that the language has succeeded and it will be time to "do a victory dance".

It has often been said that the merging of Rust into the kernel tree will be done on an experimental basis; if it doesn't work out, it can be removed again. Ojeda said that the developers working on Rust for Linux would like to know how long the trial period is likely to be. He did not really get an answer from the group, though.

Instead, Bottomley suggested that, rather than bringing in Rust, it might
be better to just move more Rust-like features into C. Ojeda said that he
has actually been working with the C language committee to push for that to
happen, but any such change will take a long time if it happens at all.
Christoph Hellwig said that this sort of change will have to happen anyway
unless the plan is to rewrite the whole kernel in Rust; he was not pleased
at the idea of rewriting working code in a new language. Perhaps the
[sparse](/Articles/689907/) static analyzer could be enhanced to
do more Rust-like checking, he
said. Ojeda answered that the result of such efforts would be like having
Rust — but much later.

Hellwig continued that the adoption of Rust-like features could be done incrementally over time. It would be "strictly worse than starting in Rust", but the kernel community has a massive code base to manage. There needs to be a way to get the benefits of a Rust-like language into all of that C code, he said. Cook said he's been pushing compiler developers to create safer C dialects as well.

Ts'o brought the session to a conclusion by noting that language design is a long-term research project; perhaps the group should focus on policy issues for the next year instead. Torvalds said that he would like to see the groups running continuous-integration testing services to incorporate Rust testing — something that is already happening. Laurent Pinchart said that the Rust developers need to be ready to provide support to the kernel community in the early days; developers will pick things up quickly and be able to help each other after a while. Torvalds added that Rust isn't that terrible in the end; "it's not Perl".

When asked about documentation, Ojeda said that the Rust developers are trying to improve on the documentation that has been done on the C side. The Rust documentation mechanism makes it easy to ensure that examples are actually tested, for example. They are adhering to rules on how unsafe blocks should be explained.

As time ran out, Matthew Wilcox asked whether kernel developers should be
writing idiomatic Rust code, or whether they will be writing "C in Rust".
Ojeda answered that code might be more C-like toward the beginning;
adoption of more advanced features (such as async) might take longer.
Gleixner asked what could be done to prevent developers from using unstable
features (once the features used by the kernel are stabilized); the answer
was to specify the version of the compiler to be used with kernel
development.

Index entries for this article | |
---|---|

|


[Development tools/Rust](/Kernel/Index#Development_tools-Rust)[Conference](/Archives/ConferenceIndex/)[Kernel Maintainers Summit/2022](/Archives/ConferenceIndex/#Kernel_Maintainers_Summit-2022) Posted Sep 20, 2022 1:38 UTC (Tue)
by
Posted Sep 20, 2022 22:28 UTC (Tue)
by
Posted Sep 21, 2022 14:11 UTC (Wed)
by
Posted Sep 21, 2022 5:56 UTC (Wed)
by
Either you end up with something that accepts all existing programs (maintains backwards compatibility) or with something that rejects the existing programs that do unsafe things, both isn't possible at the same time.
Of course the desire to keep the old code around is also at odds with significantly improving it. If you have a language with significantly improved idioms and safety features (e.g. Rust's Result instead of inline error codes) you would still have to deal with the fact that 99% of your code is written to not take advantage of them. And if you have to rewrite all your code anyway, why not rewrite it in a safer new language?
In my experience two languages that are very similar (e.g. C and C+retrofitted safety features) are much harder to keep apart in your head too than two languages that are significantly different.
Posted Sep 21, 2022 6:51 UTC (Wed)
by
Posted Sep 21, 2022 13:30 UTC (Wed)
by Except it's not really possible. Think something like In theory it should be possible to keep “new, clean code” and “old, dirty, code” clearly separated and then slowly rewrite things, but if you consider how long it takes to, e.g.,
Posted Sep 21, 2022 9:03 UTC (Wed)
by
Posted Sep 21, 2022 10:52 UTC (Wed)
by
If you try and enforce correctness, the language becomes unusable. Especially if you try and enforce the *wrong* mathematical model (Which is why I rail against SQL and relational - imnsho they've picked the wrong model, sets instead of lists ...). (Correctness is a property of a mathematical model, not of the scientific "does it actually work in the real world.)
C just doesn't have a model. C++ appears to try and impose a model on top of C.
Where Rust appears to score is that like Modula-2, it has a "strict model with escape hatches". So like C you can do anything, but the language makes it absolutely clear that you are gambling with whether it will work ...
And the problem with C is that the gcc guys are apparently trying to enforce a model that does not mesh with the way the kernel works, hence all these "escape hatch" flags, and maybe why some kernel guys are keen to try Rust. Modula-2 was before its time ... :-)
Cheers,
Posted Sep 21, 2022 13:03 UTC (Wed)
by
The "unsafe" keyword allows unrestricted liberties, including inline assembly. Interestingly, "unsafe" can also be read as "trusted". Safe Rust doesn't trust, it verifies.
Posted Sep 21, 2022 13:21 UTC (Wed)
by
Hmmm, that's a VERY interesting take ...
Cheers,
Posted Sep 21, 2022 13:40 UTC (Wed)
by So very true. Unsafe Rust forms But And newcomers invariably tried to add stuff to the “trusted” side! I guess logic was: it's “trusted”, thus it's obviously “better”. But
Posted Sep 21, 2022 23:10 UTC (Wed)
by
// SAFETY: After filling holes, all items are in contiguous memory.
These should live next to unsafe { /* ... */ } blocks, the compiler can't read your safety rationale, but a human can, and it can really help distinguish between cases where you're an idiot and this code, though it looked wrong to you, is correct; and cases where you're a genius, and this code even though it looked right to its author is actually wrong and needs fixing. If the safety rationale makes a claim that is false, that's a problem. At the least, we need a patch to the rationale. But, maybe the code is wrong too.
[
][
]## Next steps for Rust in the kernel

**jhoblitt** (subscriber, #77733)
[[Link](/Articles/908716/)]

[
]## Next steps for Rust in the kernel

**mirabilos** (subscriber, #84359)
[[Link](/Articles/908822/)] (1 responses)

[
]## Next steps for Rust in the kernel

**Tuna-Fish** (guest, #61751)
[[Link](/Articles/908898/)]

[
]## Next steps for Rust in the kernel

**taladar** (subscriber, #68407)
[[Link](/Articles/908835/)] (8 responses)




[
]## Next steps for Rust in the kernel

**pbonzini** (subscriber, #60935)
[[Link](/Articles/908839/)] (1 responses)

[
]

> Both would have to be per-file opt-ins, of course.
## Next steps for Rust in the kernel

**khim** (subscriber, #9252)
[[Link](/Articles/908859/)]
[std::align](https://en.cppreference.com/w/cpp/memory/align): if such low-level functions are not properly marked that all these “escape analysis” quickly turns into farce.[remove strlcpy](https://lwn.net/Articles/905777/)… it doesn't look feasible at all.[
]## Next steps for Rust in the kernel

**linusw** (subscriber, #40300)
[[Link](/Articles/908849/)] (5 responses)

[https://people.kernel.org/linusw/rust-in-perspective](https://people.kernel.org/linusw/rust-in-perspective)

[
]## Next steps for Rust in the kernel

**Wol** (subscriber, #4433)
[[Link](/Articles/908852/)]






Wol

[
]## Next steps for Rust in the kernel

**oxidizer** (guest, #161043)
[[Link](/Articles/908854/)] (3 responses)


[
]## Next steps for Rust in the kernel

**Wol** (subscriber, #4433)
[[Link](/Articles/908860/)]



Wol

[
]## Next steps for Rust in the kernel

**khim** (subscriber, #9252)
[[Link](/Articles/908894/)] (1 responses)
[TCB](https://en.wikipedia.org/wiki/Trusted_computing_base) which “normal” safe Rust uses to implement “business logic”.`unsafe`

keyword is better. I worked on a codebase which was similarly separated into “trusted” and “untrusted” components.`unsafe`

just doesn't feel like that. People know you can add `unsafe`

code, but the name itself prompts them to be careful.[
]## Next steps for Rust in the kernel

**tialaramex** (subscriber, #21167)
[[Link](/Articles/908944/)]