Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
|
|

A process for handling Rust code in the core kernel

By Jonathan Corbet
March 27, 2025

LSFMM+BPF
The 2024 Linux Storage, Filesystem, Memory-Management, and BPF Summit included a tense session on the use of Rust code in the kernel's filesystem layer. The Rust topic returned in 2025 in a session run by Andreas Hindborg, with a scope that also covered the storage and memory-management layers. A lot of progress has been made, and the discussion was less adversarial this year, but there are still process issues that need to be worked out.

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.

[Andreas
Hindborg] 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
KernelDevelopment tools/Rust
ConferenceStorage, Filesystem, Memory-Management and BPF Summit/2025


to post comments

Quick notes

Posted Mar 27, 2025 15:10 UTC (Thu) by ojeda (subscriber, #143370) [Link] (21 responses)

A few quick notes for completeness... I hope they are helpful.

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

Quick notes

Posted Mar 27, 2025 16:39 UTC (Thu) by tlamp (subscriber, #108540) [Link] (14 responses)

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

Rust 1.85 is in fact already available in the Debian Trixie repository:
https://packages.debian.org/source/trixie/rustc

Quick notes

Posted Mar 27, 2025 16:58 UTC (Thu) by bunch (subscriber, #18522) [Link] (13 responses)

As a side question: why do maintainers insist on using distributions provided rustc instead of using rustup to install it?

Quick notes

Posted Mar 27, 2025 17:19 UTC (Thu) by Conan_Kudo (subscriber, #103240) [Link] (10 responses)

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

Posted Mar 27, 2025 20:34 UTC (Thu) by pbonzini (subscriber, #60935) [Link] (9 responses)

The same in fact is true of anything that ships as a Deb or rpm (or whatever) package in a distro—foe example Firefox. They won't be using rustup.

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.

Quick notes

Posted Mar 28, 2025 10:31 UTC (Fri) by dottedmag (subscriber, #18590) [Link] (8 responses)

Hear, hear.

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.

Quick notes

Posted Mar 28, 2025 11:06 UTC (Fri) by pbonzini (subscriber, #60935) [Link]

And many others don't want to be in that business at all.

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

Quick notes

Posted Mar 28, 2025 15:09 UTC (Fri) by nim-nim (subscriber, #34454) [Link] (6 responses)

People keep saying that but no one has managed to produce a working upstream-binary-distribution yet.

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.

Quick notes

Posted Mar 29, 2025 15:28 UTC (Sat) by surajm (subscriber, #135863) [Link] (3 responses)

If you look how projects like chromium or fuchsia are built, they maintain almost all of their third party dependencies as prebuilts which you download alongside the git repo. It's realistically the only way, short of creating a docker container, to ensure a consistent set of tooling and dependencies are available without needing to depend on potentially less trustworthy entities (eg crates.io, npm, or what have you) that might change the package contents when you try to fetch them.

Quick notes

Posted Mar 31, 2025 8:33 UTC (Mon) by nim-nim (subscriber, #34454) [Link] (1 responses)

Exactly like distributions that maintain a repository of trusted binary prebuilds in rpm or deb format then. Once you need to ensure a minimum amount of accountability, no one plays the direct binary download from the binary upstream game.

Quick notes

Posted Mar 31, 2025 8:49 UTC (Mon) by dottedmag (subscriber, #18590) [Link]

I do whenever I can. The solution is trivial, it's called "record a checksum and check it".

Quick notes

Posted Mar 31, 2025 8:48 UTC (Mon) by dottedmag (subscriber, #18590) [Link]

There are still packaging systems and repositories in 2025 that don't provide checksums of downloads and do at least automatic ToFU, really? If yes, then it's terrifying.

Quick notes

Posted Mar 31, 2025 23:55 UTC (Mon) by MrWim (subscriber, #47432) [Link] (1 responses)

> If anything, the monorepo FAANGS favor is a return to a more centralised and more sourcecode-oriented distribution than the Debians and Fedoras provide.

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.

Quick notes

Posted Apr 1, 2025 8:29 UTC (Tue) by dottedmag (subscriber, #18590) [Link]

Yes, source-code oriented, or even just «useruser-modifications oriented».

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.

Quick notes

Posted Mar 27, 2025 19:12 UTC (Thu) by ojeda (subscriber, #143370) [Link] (1 responses)

If you mean kernel developers, some routinely use `rustup`, or the standalone installers, or the kernel.org toolchains (which currently bundle the upstream Rust binaries for simplicity -- but that may change), or build their own compilers, etc. However, other kernel developers only want to use the toolchains provided by their distributions.

Outside of development, many end users (and the distributions themselves) want to use their distribution-provided toolchains too.

Quick notes

Posted Apr 4, 2025 12:41 UTC (Fri) by bjackman (subscriber, #109548) [Link]

I guess the distros would also like to build the kernel they distribute using the toolchain they distribute, too?

Unstable features

Posted Mar 27, 2025 18:12 UTC (Thu) by comex (subscriber, #71521) [Link] (2 responses)

From the article:

> 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
[2] https://blog.rust-lang.org/2024/08/12/Project-goals.html
[3] https://rust-lang.github.io/rust-project-goals/

Unstable features

Posted Mar 27, 2025 18:55 UTC (Thu) by ojeda (subscriber, #143370) [Link] (1 responses)

> This isn’t right, is it?

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.

Unstable features

Posted Mar 27, 2025 21:14 UTC (Thu) by ojeda (subscriber, #143370) [Link]

Quick notes

Posted Mar 28, 2025 12:24 UTC (Fri) by jgg (subscriber, #55211) [Link] (2 responses)

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

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
$ 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

So what is the make command?

$ make LLVM=1 BINDGEN=bindgen-0.65 rustavailable
***
*** Rust compiler 'rustc' is too old.
*** Your version: 1.75.0
*** Minimum version: 1.78.0

Ugh.

$ make LLVM=1 BINDGEN=bindgen-0.65 RUSTC=rustc-1.80 rustavailable
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

Uh.. OK..

$ make LLVM=1 LLVM_SUFFIX=-17 BINDGEN=bindgen-0.65 RUSTC=rustc-1.80 rustavailable
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!

Progress?

I have lots of libclang's:

$ ls /lib/x86_64-linux-gnu/libclang*
/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

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
Rust is available!

Yay, finally..

The instructions in quick-start really should say the special make command required as well.

Quick notes

Posted Mar 28, 2025 15:13 UTC (Fri) by ojeda (subscriber, #143370) [Link] (1 responses)

> You can build it, but not following the instructions

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.

Quick notes

Posted Mar 28, 2025 18:25 UTC (Fri) by jgg (subscriber, #55211) [Link]

It is not every setup, it is Ubuntu 24.04 LTS which is listed in its own section in the documentation with its own steps. Put the command that is required to make it work reliably so people can make it work. It is not easy to find all these weird make variables that are needed.

Just download it

Posted Mar 28, 2025 10:29 UTC (Fri) by dottedmag (subscriber, #18590) [Link]

"Is not available in my distribution" sounds like a weak argument for something that aids in development.

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
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]
%

So for manual work it's one download away, and even for CI it's a one download and one checksum verification away.


Copyright © 2025, 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