|
|
Subscribe / Log in / New account

Next steps for Rust in the kernel

By Jonathan Corbet
September 19, 2022

Maintainers Summit
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.

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.

[Miguel Ojeda] 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 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
KernelDevelopment tools/Rust
ConferenceKernel Maintainers Summit/2022


to post comments

Next steps for Rust in the kernel

Posted Sep 20, 2022 1:38 UTC (Tue) by jhoblitt (subscriber, #77733) [Link]

People who live in C houses shouldn't (void)stones.

Next steps for Rust in the kernel

Posted Sep 20, 2022 22:28 UTC (Tue) by mirabilos (subscriber, #84359) [Link] (1 responses)

This is an unportable catastrophe…

Next steps for Rust in the kernel

Posted Sep 21, 2022 14:11 UTC (Wed) by Tuna-Fish (guest, #61751) [Link]

How? By the time Rust will be used for anything other than toy drivers, Rust-GCC should be done, so Linux with Rust will compile anywhere that Linux without Rust can.

Next steps for Rust in the kernel

Posted Sep 21, 2022 5:56 UTC (Wed) by taladar (subscriber, #68407) [Link] (8 responses)

What is it with all those people who don't understand that many (especially safety) features can not be retrofitted into established languages while maintaining backwards compatibility?

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.

Next steps for Rust in the kernel

Posted Sep 21, 2022 6:51 UTC (Wed) by pbonzini (subscriber, #60935) [Link] (1 responses)

The idea was to start with very simple stuff like forcing manual conversion of integer types and explicitly noting in the prototypes which pointer arguments that are can escape the called functions. Both would have to be per-file opt-ins, of course.

Next steps for Rust in the kernel

Posted Sep 21, 2022 13:30 UTC (Wed) by khim (subscriber, #9252) [Link]

> Both would have to be per-file opt-ins, of course.

Except it's not really possible. Think something like std::align: if such low-level functions are not properly marked that all these “escape analysis” quickly turns into farce.

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., remove strlcpy… it doesn't look feasible at all.

Next steps for Rust in the kernel

Posted Sep 21, 2022 9:03 UTC (Wed) by linusw (subscriber, #40300) [Link] (5 responses)

As I was rambling on in my own little bubble over at the kernelorg blog about Rust, I came to the conclusion that what we are doing with Rust is to increase the abstraction of the language, not just making it more safe, but abstraction does bring safety. But since this point has been stressed since 1968 there is a reason why C has prevailed, and it is exactly the (casting) and general ability to act like a big macro assembler. Doing C safe would mean to remove exactly these features and thereby remove the appeal of C. (This is not really my opinion, but extrapolated from Niklaus Wirth.)
https://people.kernel.org/linusw/rust-in-perspective

Next steps for Rust in the kernel

Posted Sep 21, 2022 10:52 UTC (Wed) by Wol (subscriber, #4433) [Link]

This is the classic Pascal / Modula dichotomy.

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,
Wol

Next steps for Rust in the kernel

Posted Sep 21, 2022 13:03 UTC (Wed) by oxidizer (guest, #161043) [Link] (3 responses)

Good comments about C, however Rust doesn't have an issue here.

The "unsafe" keyword allows unrestricted liberties, including inline assembly. Interestingly, "unsafe" can also be read as "trusted". Safe Rust doesn't trust, it verifies.

Next steps for Rust in the kernel

Posted Sep 21, 2022 13:21 UTC (Wed) by Wol (subscriber, #4433) [Link]

> The "unsafe" keyword allows unrestricted liberties, including inline assembly. Interestingly, "unsafe" can also be read as "trusted". Safe Rust doesn't trust, it verifies.

Hmmm, that's a VERY interesting take ...

Cheers,
Wol

Next steps for Rust in the kernel

Posted Sep 21, 2022 13:40 UTC (Wed) by khim (subscriber, #9252) [Link] (1 responses)

So very true. Unsafe Rust forms TCB which “normal” safe Rust uses to implement “business logic”.

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

And newcomers invariably tried to add stuff to the “trusted” side! I guess logic was: it's “trusted”, thus it's obviously “better”.

But 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

Posted Sep 21, 2022 23:10 UTC (Wed) by tialaramex (subscriber, #21167) [Link]

Crucial in Rust culture is also writing safety rationales. Here's a nice succinct one from the implementation of alloc::vec::Vec

// 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.


Copyright © 2022, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds