A process for handling Rust code in the core kernel
Getting Rust code upstream
There are, Hindborg began, several paths by which Rust code gets into the
kernel, which he arranged on "the Brauner-Hellwig scale
". At the
Brauner end, some subsystems are accepting Rust code directly and
maintaining it themselves; the virtual filesystem layer (co-maintained by
Christian Brauner) is a case in point. In these subsystems, Rust patches
are simply accepted like any others.
Moving down the scale, the developers of some subsystems would like to be
able to accept Rust code directly, but the maintainers acknowledge that
they need help to do so. The kernel's module loader is an example here; to
merge that code, experts from the Rust community have been helping. Other
subsystems designate a separate sub-maintainer to handle Rust code; the
block layer was mentioned as using this model.
Then, there are the subsystems that don't handle Rust code at all; for these, code goes through the Rust trees instead. In some cases, the maintainers are willing, and will act as reviewers, but don't feel that they can handle the code directly; timekeeping was mentioned here. Finally, some subsystems are not working with the Rust developers in any way; they simply don't want to know about the Rust code. That is the case for the DMA-mapping and XArray subsystems.
None of these models are wrong, Hindborg said, but the last mentioned is the least productive of all of them. A subsystem's C maintainers know the subsystem best, so their input is needed to get the best results. He said that an understanding of Rust is not necessary to review submissions; the Rust code is extensively documented, and comments on the intended semantics of that code are the most important.
Ted Ts'o said that it would help to set more explicit expectations around testing and breakage. If Rust code is going through the regular subsystem trees, the maintainers should at least be doing build tests of that code, and there should be a defined path forward when a build break happens. If the tree doesn't build, he asked, should patches just be dropped after a certain time? Hindborg answered that, if the break is observed before merging, the patches should just be dropped right away. But mostly, he said, when a break happens, people just fix it and move on.
David Hildenbrand noted that changing a C interface could make it necessary to change a lot of Rust code to match. If the Rust code is not maintained in the same tree, it is not clear how the patches should be split. Hindborg said that such patches can be handled like any tree-wide series. If need be, the developer can create a new API and slowly convert code over to it. If a developer is having trouble making changes to Rust code, they can ask for help.
Liam Howlett said that, if he merges a change that breaks Rust code, it will cause immediate problems, such as breaking continuous-integration builds. Then the finger of blame will point at him. It is going to be important to be able to do all of these changes together. Hindborg agreed, but also pointed out that, in the block subsystem, developers make changes without worrying about the Rust side. When he gets a problem report, he fixes it within a day and all is well. Howlett answered that this approach will not scale; more subsystems using Rust will lead to more troubles. Hindborg agreed that it would be better to get all of the changes in a single series, but he didn't think he could ask that of the development community — or get it if he did ask. Petr Tesařík pointed out that breaking the Rust code could lead to trouble for developers who are trying to bisect regressions.
Hindborg asked block-subsystem maintainer Jens Axboe about his experience with accepting Rust code; Axboe answered that it has added almost no overhead at all. If something breaks, he said, he often gets a patch fixing the problem before he is even aware of it. It is all working well, but he pointed out that the block subsystem does not yet have a lot of Rust code. When asked by Hindborg, Axboe said that he does his builds with Rust enabled, but is not able to run-test everything.
Ts'o said that he had not been doing Rust-enabled builds until recently, and still does not do them regularly. The reason is that his test infrastructure is based on Debian stable, and that distribution does not have a sufficiently recent version of the Rust compiler. He has gotten things working using Debian testing, but running that distribution invites other problems. Hindborg said that this is an easy problem to solve, all that is needed is to wait. The minimum version of Rust has been 1.78.0 for a while now; over time, the problems will go away.
Matthew Wilcox said he doesn't have current Rust on his systems because he does not like being a system administrator. He leaves that work up to the distributor; until it provides a suitable compiler, he just won't have it. Jason Gunthorpe said that he had tried to do the Rust build on Ubuntu LTS, but that the instructions in the kernel documentation do not work there; Hindborg said that he would ensure that it was fixed.
Current and future status
A set of abstractions for the configfs filesystem is ready for
consideration, Hindborg said, but the maintainer team for configfs has recently
been "cut in half
" (after Christoph Hellwig stopped doing that
work). There is only one maintainer, who is not responding to email. It
turns out that the listed maintainer has retired; Hindborg was advised to
remove him from the maintainer entry and take that subsystem over.
There have been a number of advances recently, Hindborg said. The "rnull stub" (a block null-device driver) has been merged, he said, as has Rust support for 32-bit x86 systems. It is now possible to download Rust toolchains from kernel.org. Other merged code includes a user-space access module, abstractions for struct page, struct file, and struct cred, and a linked-list implementation. The rendered internal documentation is available on kernel.org.
The first "real" driver in Rust, for Applied Micro QT2025 PHY devices, has been merged. The KASAN sanitizer and Clang control-flow integrity both work with Rust code. There is an abstraction for misc devices, support for tracepoints, and for RCU read locking. The addition of the memory-management abstractions also led to some significant improvements to the virtual memory area (VMA) locking documentation, he said.
Looking forward, Hindborg said that the controversial DMA-mapping abstractions will be landing soon [that may have happened by the time you read this]. There will be support for high-resolution timers, module parameters, I/O polling, the XArray data structure, the iov_iter mechanism, and VMAs. In the longer term, the Nova graphics driver is moving forward; that will be a multi-year effort.
In his conclusion, he repeated that the minimum version of the Rust
compiler has remained at 1.78.0 since the 6.10 release, even as newer
versions have gained support. There are only four unstable features needed
by the kernel at this point, and that number will soon be zero, he said.
The compiler team includes kernel builds in its continuous-integration
testing to be sure they don't break it. The kernel, he said, is a
"flagship goal" for the Rust project; the Rust developers take the kernel
project seriously, want to make it work, and are dedicating resources toward
that end.
Index entries for this article | |
---|---|
Kernel | Development tools/Rust |
Conference | Storage, Filesystem, Memory-Management and BPF Summit/2025 |
Posted Mar 27, 2025 15:10 UTC (Thu)
by ojeda (subscriber, #143370)
[Link] (21 responses)
> The reason is that his test infrastructure is based on Debian stable, and that distribution does not have a sufficiently recent version of the Rust compiler.
Debian Trixie (the next stable, getting released in a few months) is expected to have Rust 1.85 (at least that is my understanding from our last conversations with Debian).
That version is recent enough -- it is the latest Rust compiler at the moment, in fact, and supports the just released Rust 2024 edition.
> The minimum version of Rust has been 1.78.0 for a while now; over time, the problems will go away.
Our plan is to upgrade at some point the minimum to the new Debian stable one, i.e. 1.85 (not immediately after Debian Trixie gets released, of course).
> Jason Gunthorpe said that he had tried to do the Rust build on Ubuntu LTS, but that the instructions in the kernel documentation do not work there;
I just tried Ubuntu 24.04 LTS in a fresh VM, and I could build v6.14 without issue with the versioned packages mentioned in the instructions.
Note that you also have to respect the Kconfig requirements to enable Rust, which is a bit annoying with older Rust compilers like 1.80. Please see the Ubuntu related issues at https://github.com/Rust-for-Linux/linux/issues/1127, too.
It is way easier, though, in distributions that provide newer Rust compilers, such as Fedora.
> as has Rust support for 32-bit x86 systems
Required features landed recently in `rustc` as unstable (`-Zreg-struct-return`, `-Zregparm`), but the architecture support has not been added yet (and we could be missing something else, but those two are the ones I knew for sure we needed).
> There have been a number of advances recently, (...) The first "real" driver in Rust
In case it is useful: the authors/maintainers of (some of) those efforts maintain subpages for the main users (upstream or upcoming) in our website which may be interesting to look at -- please see the "Users" sections in the left menu at https://rust-for-linux.com.
> There are only four unstable features needed by the kernel at this point, and that number will soon be zero, he said.
To clarify, this is likely referring to language unstable features, not unstable features in general. Language ones are important to avoid, because we don't want to have to rewrite source code. But, as the article/Andreas says, they are close to be done, finally, and we don't expect any change anyway.
For instance, there are a bunch of compiler flags that are needed. Please see our https://github.com/Rust-for-Linux/linux/issues/2 page for the details as usual.
> The compiler team includes kernel builds in its continuous-integration testing to be sure they don't break it.
Indeed -- this is key, and has allowed us to have confidence things work in upcoming releases and to spot issues early (only happened a couple times so far, which is good).
It also allowed us in the past to declare a minimum supported version (1.78 at the moment) and thus support several versions (so far, 8 in total, plus beta and nightly should generally work).
Please see https://rustc-dev-guide.rust-lang.org/tests/ecosystem-test-jobs/rust-for-linux.html for some details and the policy.
> The kernel, he said, is a "flagship goal" for the Rust project; the Rust developers take the kernel project seriously, want to make it work, and are dedicating resources toward that end.
Indeed, in fact, we regularly meet with them to keep making progress. They have been so far open to hear what the kernel needs and offer solutions.
Posted Mar 27, 2025 16:39 UTC (Thu)
by tlamp (subscriber, #108540)
[Link] (14 responses)
Rust 1.85 is in fact already available in the Debian Trixie repository:
Posted Mar 27, 2025 16:58 UTC (Thu)
by bunch (subscriber, #18522)
[Link] (13 responses)
Posted Mar 27, 2025 17:19 UTC (Thu)
by Conan_Kudo (subscriber, #103240)
[Link] (10 responses)
Posted Mar 27, 2025 20:34 UTC (Thu)
by pbonzini (subscriber, #60935)
[Link] (9 responses)
It doesn't have to be used everywhere. It's totally fine if a project's CI wants to use rustup to get a heads up about e.g. new additions to nightly clippy; or if rustup toolchains are recommended to users of old frozen distros that won't package that code. For example, in QEMU we will probably start requiring a rustup toolchain for Debian bookworm since Rust usage is still experimental and there's no reason for distros to enable it.
Posted Mar 28, 2025 10:31 UTC (Fri)
by dottedmag (subscriber, #18590)
[Link] (8 responses)
We're no longer in 1996 when software was distributed in tarballs, libc interface has not yet solidified and distributions carried patches that caused C ABI incompatibilites. Many upstreams are competent to provide binaries nowadays.
Posted Mar 28, 2025 11:06 UTC (Fri)
by pbonzini (subscriber, #60935)
[Link]
You still have cases where different distros of Linux carry different versions of glibc or musl (cue the history of Python manylinux/musllinux). You have projects that also care about Windows and perhaps the three BSDs (four if you count Dragonfly), or that would have to produce architectures other than x86. You also have macOS for which cross compilation is of doubtful legal status. And so on...
Posted Mar 28, 2025 15:09 UTC (Fri)
by nim-nim (subscriber, #34454)
[Link] (6 responses)
Once you get to the point where you try to release the kind of full system users want (ideally, preinstalled) you quickly reinvent a distribution. Many is not all nor all the time, look up the trainwreck that OpenH264 proved and that’s a single binary component produced by a well-financed corporation.
If anything, the monorepo FAANGS favor is a return to a more centralised and more sourcecode-oriented distribution than the Debians and Fedoras provide.
Posted Mar 29, 2025 15:28 UTC (Sat)
by surajm (subscriber, #135863)
[Link] (3 responses)
Posted Mar 31, 2025 8:33 UTC (Mon)
by nim-nim (subscriber, #34454)
[Link] (1 responses)
Posted Mar 31, 2025 8:49 UTC (Mon)
by dottedmag (subscriber, #18590)
[Link]
Posted Mar 31, 2025 8:48 UTC (Mon)
by dottedmag (subscriber, #18590)
[Link]
Posted Mar 31, 2025 23:55 UTC (Mon)
by MrWim (subscriber, #47432)
[Link] (1 responses)
I wrote a bit about that here: https://blog.williammanley.net/2020/05/25/unlock-software... :
> By doing so the huge proprietary megacorp gains more of the benefits of the fact that the software is free (as in freedom) than the free-software distros can!
I’d love to see the major distros pursue the goal of becoming more sourcecode-oriented as you put it, unlocking the ability to modify the software they provide.
Posted Apr 1, 2025 8:29 UTC (Tue)
by dottedmag (subscriber, #18590)
[Link]
It's a pretty sad state of affairs that the only games in town are Gentoo whose authors haven't even gotten around to compile ARM64 handbook, and NixOS with its horrendous language and NixPkgs repeating all the mistakes BitBake-based OpenEmbedded repository did, namely moving build logic from the build tool into the packages repository, thus making it less discoverable, underdocumented and changeable, diluting the contract between the package repository and the package description.
Posted Mar 27, 2025 19:12 UTC (Thu)
by ojeda (subscriber, #143370)
[Link] (1 responses)
Outside of development, many end users (and the distributions themselves) want to use their distribution-provided toolchains too.
Posted Apr 4, 2025 12:41 UTC (Fri)
by bjackman (subscriber, #109548)
[Link]
Posted Mar 27, 2025 18:12 UTC (Thu)
by comex (subscriber, #71521)
[Link] (2 responses)
> There are only four unstable features needed by the kernel at this point, and that number will soon be zero, he said.
This isn’t right, is it? According to [1], there is only a small set of unstable features (indeed, four of them) allowed in *drivers*, but the core kernel crate still uses a large number of unstable features.
That said, stabilizing the features needed by Rust for Linux is one of the Rust Project’s “flagship goals” [2] [3], and I’ve seen active work on many of those features happening in parallel, so that number may go down more quickly than you might expect.
[1] https://rust-for-linux.com/unstable-features
Posted Mar 27, 2025 18:55 UTC (Thu)
by ojeda (subscriber, #143370)
[Link] (1 responses)
No, but because the situation is actually better! :)
Even if one counts the `kernel` crate, it is essentially two language features left: `arbitrary_self_types` and `derive_coerce_pointee`. For other code, it is just the former.
The reason is that some of the features we need to list are meant to support older compilers that were released when they were not stable.
I will update the "Unstable features" page a bit to clarify this -- thanks!
This does not mean we may not use a new feature if it is really convenient and everyone is on board and so on. But we are finally very close to being able to say we don't use unstable Rust, language-wise.
Posted Mar 27, 2025 21:14 UTC (Thu)
by ojeda (subscriber, #143370)
[Link]
Posted Mar 28, 2025 12:24 UTC (Fri)
by jgg (subscriber, #55211)
[Link] (2 responses)
You can build it, but not following the instructions in Documentation/rust/quick-start.rst:
$ sudo apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 rust-1.80-clippy
So what is the make command?
$ make LLVM=1 BINDGEN=bindgen-0.65 rustavailable
Ugh.
$ make LLVM=1 BINDGEN=bindgen-0.65 RUSTC=rustc-1.80 rustavailable
Uh.. OK..
$ make LLVM=1 LLVM_SUFFIX=-17 BINDGEN=bindgen-0.65 RUSTC=rustc-1.80 rustavailable
Progress?
I have lots of libclang's:
$ ls /lib/x86_64-linux-gnu/libclang*
Maybe don't automatically pick the wrong one :\
$ make LLVM=1 LLVM_SUFFIX=-17 BINDGEN=bindgen-0.65 RUSTC=rustc-1.80 LIBCLANG_PATH=/lib/x86_64-linux-gnu/libclang-17.so.1 rustavailable
Yay, finally..
The instructions in quick-start really should say the special make command required as well.
Posted Mar 28, 2025 15:13 UTC (Fri)
by ojeda (subscriber, #143370)
[Link] (1 responses)
You can definitely argue the instructions could be more detailed, but the existing instructions are currently meant as examples on installing the toolchain, not as a full guide on building the kernel for each particular distribution/LTS/set of packages/setup.
> Maybe don't automatically pick the wrong one :\
Hmm... I don't think we should automatically override whatever the user's tool (or its distribution) does.
> The instructions in quick-start really should say the special make command required as well.
I wouldn't say it is really special. In a fresh 24.04 LTS, using the install command provided, this works:
make LLVM=1 RUSTC=rustc-1.80 BINDGEN=bindgen-0.65 rustavailable
`LLVM=1` is common and `RUSTC`/`BINDGEN` are needed just like in the C side when using different binaries.
The biggest pitfalls are the `RUST_LIB_SRC` one and the `bindgen` bugs -- they are mentioned and they were reported to upstream Ubuntu.
Now, yes, an example `make` for cases that we know that work could help, or perhaps a list of related variables, but we cannot try to cover every setup either, so it is a balance.
Over time, this will get easier, e.g. Ubuntu 25.04 will be better -- no versioned packages needed.
And others like Fedora just work already.
Posted Mar 28, 2025 18:25 UTC (Fri)
by jgg (subscriber, #55211)
[Link]
Posted Mar 28, 2025 10:29 UTC (Fri)
by dottedmag (subscriber, #18590)
[Link]
Rust is not Go whose distributed prebuilt binaries are statically linked, but still the binary releases of Rust are pretty much self-contained:
% x86_64-linux-gnu-readelf -a ./rustc/bin/rustc | grep NEEDED
So for manual work it's one download away, and even for CI it's a one download and one checksum verification away.
Quick notes
Quick notes
https://packages.debian.org/source/trixie/rustc
Quick notes
Because that is how the Linux kernel will be built in practice. Linux is delivered through distributions, so if stuff doesn't work through distribution tooling, it won't get shipped. Rustup is a non-entity for Linux Rust development for this reason. It needs to work with conventional distribution-provided tooling.
Quick notes
Quick notes
Quick notes
And many others don't want to be in that business at all.
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Quick notes
Unstable features
[2] https://blog.rust-lang.org/2024/08/12/Project-goals.html
[3] https://rust-lang.github.io/rust-project-goals/
Unstable features
Unstable features
Quick notes
$ export RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library
$ make LLVM=1 rustavailable
***
*** Rust bindings generator 'bindgen' could not be found.
***
***
*** Please see Documentation/rust/quick-start.rst for details
*** on how to set up the Rust support.
***
make[1]: *** [/tmp/x/Makefile:1798: rustavailable] Error 1
make: *** [Makefile:251: __sub-make] Error 2
***
*** Rust compiler 'rustc' is too old.
*** Your version: 1.75.0
*** Minimum version: 1.78.0
Failed to run rustfmt: No such file or directory (os error 2) (non-fatal, continuing)
***
*** Rust bindings generator 'bindgen-0.65' < 0.69.5 together with libclang >= 19.1
*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824),
*** unless patched (like Debian's).
*** Your bindgen version: 0.65.1
*** Your libclang version: 19.1.7
***
clang: unknown C compiler
Failed to run rustfmt: No such file or directory (os error 2) (non-fatal, continuing)
***
*** Rust bindings generator 'bindgen-0.65' < 0.69.5 together with libclang >= 19.1
*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824),
*** unless patched (like Debian's).
*** Your bindgen version: 0.65.1
*** Your libclang version: 19.1.7
***
***
*** libclang (used by the Rust bindings generator 'bindgen-0.65')
*** version does not match Clang's. This may be a problem.
*** libclang version: 19.1.7
*** Clang version: 17.0.6
***
***
*** Please see Documentation/rust/quick-start.rst for details
*** on how to set up the Rust support.
***
Rust is available!
/lib/x86_64-linux-gnu/libclang-17.so.1@ /lib/x86_64-linux-gnu/libclang-19.so.19
/lib/x86_64-linux-gnu/libclang-17.so.17 /lib/x86_64-linux-gnu/libclang-cpp.so.17@
/lib/x86_64-linux-gnu/libclang-18.so.1@ /lib/x86_64-linux-gnu/libclang-cpp.so.18@
/lib/x86_64-linux-gnu/libclang-18.so.18 /lib/x86_64-linux-gnu/libclang-cpp.so.18.1@
/lib/x86_64-linux-gnu/libclang-19.so.1@ /lib/x86_64-linux-gnu/libclang-cpp.so.19.1
Rust is available!
Quick notes
Quick notes
Just download it
0x0000000000000001 (NEEDED) Shared library: [librustc_driver-fdfc7fb14758cf9e.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
%