Why Rust Is Coming to the Linux Kernel: Greg KH on Bindings, Bugs, and Change
The Pragmatic EngineerIn this podcast excerpt, Linux kernel developer Greg KH is asked whether Linux might ever support Rust, or any language besides C. Rust is already in the kernel, Greg explains, and the harder question is how it fits alongside an enormous existing C codebase. Their position is that Rust is not a silver bullet. Still, they argue it should make drivers easier to write, it would eliminate a large class of common bugs, and the kernel has reached a tipping point where new Rust code will start appearing.
Rust Is Already There, Mostly as Bindings
Greg answers the opening question by noting that the kernel already contains about 25,000 lines of Rust. Most of that code is bindings rather than real functionality. One visible exception is a feature from the latest release: when the kernel crashes, it can display a QR code that you photograph to retrieve the crash dump. That QR code generator is written in Rust.
Greg describes the history this way. The Rust for Linux developers had been working on the effort for a long time. A couple of years ago they came to the kernel maintainers and said they thought they were ready and asked whether the kernel wanted it. Greg says the maintainers agreed to try it as an experiment, since the Rust developers were willing to do the work.
Why Drivers Are Harder Than Core Code
Greg makes a point that may seem backwards: it would be easier to write a core piece of Linux in Rust than to write a driver. Drivers draw on everything else in the kernel. They deal with blocking, input and output, the driver model, USB ports, and more. Drivers can be very small precisely because they borrow resources from the rest of the kernel.
In Rust, each of those connections needs a binding, an intermediate layer between the C code and the Rust code. Greg explains that the C kernel has very opinionated ideas about how it handles objects and memory, including its own memory model. Rust has equally opinionated ideas about the same things. Getting the two to mesh is tough, and Greg calls the resulting binding code "the most crazy complex Rust code you've ever seen." As a self-described new Rust developer, Greg says they can barely read the bindings but trust the people writing them.
So a binding has to be written for each part of the kernel before Rust drivers can use it. The QR generator was simple because it was a single function. Over the past couple of years, people have been writing bindings and building example drivers, including a new disk driver implemented in both C and Rust for comparison.
Performance Gaps and the Rust Toolchain
Those comparisons showed that Rust code still has some performance issues relative to C, according to Greg, because kernel developers can use tricks in C that Rust can't do yet. Greg describes this as a tooling problem that the Rust developers are working on. Some of the core developers of the Rust language are also Linux kernel developers, Greg notes, and they have always wanted Rust to work for Linux.
What "Memory Safety" Actually Means at the Kernel Level
Greg is careful to separate Rust's memory safety from any claim that Rust code can't crash the kernel. At the kernel level, memory safety does not stop you from overwriting things. In Greg's framing, it means the memory you pass around is clearly owned or not owned, and things get cleaned up properly when they go out of scope.
Greg says they have seen every kernel bug for the past 18 years and estimates that half of them would be fixed by Rust. Those are the "stupid one-off bugs": overwriting an array by one, forgetting to clean up an error path, forgetting to unlock a lock. Logic bugs remain possible in Rust, and the interviewer and Greg agree those will always exist.
The QR code feature itself serves as the cautionary example. The C code passed the Rust code a pointer to a buffer along with the buffer size. The Rust code never checked the size and wrote right over memory. Greg's conclusion is that you can write memory-unsafe code in Rust and crash things with it. Memory safety here is about the safety of object life cycles, not the removal of all bugs.
The Case for Rust in Drivers
Greg still believes Rust needs to come in, mainly because it should make drivers easier to write. Devices are dynamic and can be yanked out at any time. Handling the lifetime rules and reference counting correctly is very tricky. Greg says there are parts of the kernel that still don't get this right, and the developers know it.
Greg also points to a side effect: Rust is forcing the kernel to document its C code better and to clean it up. Greg has had to clean up code in the driver core and found they could do things better and safer in C to make Rust easier. Greg says these improvements would remain even "if Rust disappeared tomorrow." The effort is making developers rethink a lot of existing kernel code.
Resistance, and Being Wrong on Both Sides
Greg acknowledges that many core kernel developers resist this. Some dislike change, and some dislike multiple languages in one project. One core developer said they didn't like working on a multi-language project because it's tricky. Greg says those developers are free to feel that way and that the Rust effort isn't stepping on anybody's toes. A lot of the conflict, in Greg's view, comes from miscommunication and from people.
Greg shares a personal example. Many years ago Greg wrote the kernel's driver core, which governs how drivers work in the system, and Rust needed a binding for it. When Greg saw the proposed binding code, their reaction was that it was horrible, wouldn't work, and was miserable. So Greg met with the developers at a Rust Linux conference, where Greg says the developers seem to have given a whole presentation just for them.
The outcome, as Greg tells it, was that both sides were wrong. The Rust developers had written about a thousand lines of Rust to do what Greg did in two lines of C. When Greg asked why, they said they hadn't wanted to change the C code. Greg told them the C code could change. Greg had only written it that way because it was easy in C, and changing it would eliminate a thousand lines of Rust. Greg's lesson is that progress came from understanding each other's problems and working together.
Real Drivers Are Starting to Appear
As a result, Greg says, the kernel now has bindings good enough to write some drivers. Red Hat developers are starting to write the new Nvidia GPU drivers in Rust and are putting proposals out. The GPU drivers for Apple MacBooks are also written in Rust. Greg notes those patches are not merged but are written and approved on a fork, and says they work great. Graphics drivers have many complex object life cycle issues, and Greg says Rust makes those much easier to handle.
Greg also expects many "simple stupid drivers" for hardware devices to be written in Rust. Many drivers only need to read and write some memory bits, which Greg says is easy in Rust and can take less code than in C. With the infrastructure now in place, Greg believes the kernel has hit the tipping point and will start seeing new Rust code.
Government Mandates and Linux's Future
Greg ties the shift partly to outside pressure, pointing to government mandates against using memory-unsafe languages like C in products. Because Greg wants Linux to succeed, they say the kernel will have to change. Going forward, Greg's stance is that if you want to write in Rust, you can.
Protecting the 40 Million Lines of C
Greg stresses that the kernel still has 40 million lines of C, and says nobody is going to rewrite it in Rust ("Don't worry about that"). Very good developers are working on reducing the problems in the C code. Greg mentions that the kernel now has bounds checking, along with what they call "seat belts and airbags" that protect C code from doing stupid things. Kernel developers are also working with compiler authors to add new C extensions that make C code safer, because the goal is to protect the code that exists today.
Greg supports this approach with a Google publication. As Greg describes it, Google wrote its new code in Rust over the past couple of years, left the old code alone, and became overwhelmingly more secure. Greg's explanation is that bugs decay over time: older code still has bugs, but most bugs appear in new code.
An Experiment That Can Still Be Reversed
When the interviewer says Greg seems excited about Rust, Greg frames it as evolution: see what happens, and if it fails tomorrow, the kernel can rip it out. What matters to Greg is that developers are willing to do the work and it doesn't intrude on other people's code. The interviewer links this to Linux's "show the work" culture: Rust got in and is progressing because people keep demonstrating that it works and solves their problems.
Greg closes with the question of other languages. People ask why not Zig or Hare. Greg says those are good languages, but nobody has proposed them. Greg adds that the developers behind those languages probably don't care about Linux, which Greg considers fine, since they don't have to.
Do you think Linux at some point might support Rust? Or, you know, what is your thinking of doing things outside of C?
So, we have 25,000 lines of Rust in the kernel already.
Oh.
We do.
Okay, awesome.
Yeah. So, most of that is just bindings. There's no real functionality. In the latest release, if the kernel crashes, it'll put up a QR code. You can take a picture of it to get the crash dump. That code is written in Rust.
Oh, nice.
That's in Rust. So, the Rust for Linux developers have been working for a long time. A couple years ago, they came to us and said, "We think we're ready to do this. Do you want it?" And we said, "Yeah, let's try this experiment. You're willing to do the work? Who am I to tell no to?" I mean, it's
Linux.
Yeah, I mean, it's... Now, the problem with Linux and Rust is it'll be easier to write a core piece of Linux in Rust than it would be to write a driver. Drivers consume from everywhere in the kernel.
Mhm.
So, you want to talk blocking. You want to talk input and output. You want to talk to the driver model. Talk to the USB port. All this stuff. Drivers can be really tiny because they take resources from the rest of the kernel.
In Rust, you need to have a binding between the C code and the Rust code. There's an intermediate layer. The kernel in C has these very opinionated model ideas of how it handles objects and how it does memory, and it has its memory model. Rust has its very opinionated model of how it does this same type of idea. This meshing is tough. This meshing is also the most crazy complex Rust code you've ever seen. So, for a new Rust developer like me, I can barely read the bindings, but I trust other people are doing it.
So, yes. So, the trick is we now need to write a binding for every different part of the kernel in order to write Rust code, a Rust driver. If you want to do the QR generator, that's simple. That was just one function.
So, over the past couple years, people have been writing bindings to try and do things. We've had a bunch of example drivers, like a new disk driver, this writer driver in C versus Rust. It turns out there are still some performance issues with Rust code versus C code because we can do some tricks in C that they can't do yet in Rust. That's in the tooling, and the Rust developers are doing it. The core Rust developers that do the language, some of them are Linux kernel developers. They've always wanted Rust to be working for Linux.
The Rust model's good. Memory safety at our level does not mean that you can't crash the kernel. You can still overwrite things. Memory safety in Rust just means the memory that you pass around you think you have ownership of or it isn't in ownership of. And when things go out of scope, they'll get cleaned up properly.
So I've seen every single kernel bug for the past 18 years. Half of them will be fixed with Rust. It's just going to be fixed with Rust. It's the stupid off-by-one bugs. It's the "Oops, I overwrote an array and I didn't realize it by one." "Oops, I forgot to clean up this error path. I forgot to unlock this lock." It's stupid little things like that. There's logic bugs, of course. You can write logic bugs in Rust.
You'll always have those.
Right. So, famously, the QR code that was done in Rust: C passed into the Rust code a pointer to a buffer and the buffer size. The Rust code forgot to look at how big the buffer was, and it scribbled right over memory. So you can write memory-unsafe code in Rust just fine. And you can crash things in Rust. And so memory safety here means the safety of object life cycles and things like that. It doesn't mean it's going to remove all bugs. It's not a golden bullet or anything, a silver bullet.
But I think, yes, I think Rust needs to come in because it should be easier to write drivers in this stuff. We have a lot of issues with lifetime rules of when you yank out a device; devices are dynamic. And dealing with the reference counting of things like that is very tricky to get right. There's parts in the kernel where we still do not have it right, and we know we don't have it right.
Rust is forcing us to actually document our C code better. And it's cleaning up. So, if Rust disappeared tomorrow, I've had to clean up code in the driver core. It's like, "Oh, yeah, I guess we can do things better and safer in the C code in order to make Rust easier." And we have. And so, it's making us rethink how we do a lot of our existing code in the kernel.
To be fair, a lot of core kernel people are resistant to that. They don't like change. They don't like different languages. One core kernel developer said, "I don't like working with a project that has multiple languages in it," just because it's tricky. And they are free to do that. We're not stepping on anybody's toes. A lot of it's miscommunication, and a lot of it comes down to people again.
Namely, in this binding: I wrote the driver core many, many years ago, of how drivers work in the kernel. There had to be a binding for that in Rust. This code I saw, I said, "This is horrible. This isn't going to work at all. It's miserable." And I went and actually met with the developers. There's a Rust Linux conference. We sat down. I think they gave a whole presentation just for me.
Turns out I was wrong, and they were wrong. We both were wrong. And they were doing crazy things, like they had a thousand lines of Rust code for what I do in two lines of C code. I'm like, "Well, why?" They're like, "Well, we didn't want to change the C code." I'm like, "We can change the C code, because I just did that because it was easy in C, but if I change that, you get rid of a thousand lines of Rust. Let's do that." And then again, it comes down to, "Okay, understanding what your problems are, understanding what my problems are, and let's work together." And now we have bindings in the kernel that you can actually write some drivers with.
And the Red Hat developers are starting to write the new Nvidia GPU drivers in Rust. And they're starting to put proposals out there. The Apple GPU drivers for the Apple MacBooks are written in Rust. Those patches are not merged, but they're written in Rust and approved on a fork. That works great. There's a whole bunch of crazy object life cycle issues with graphics drivers, and Rust makes it a lot easier for them to do.
I think you'll see a lot more of the simple, stupid drivers for hardware devices being written in Rust, because all I want to do is read and write to some random memory bits, and it's really easy to do that in Rust, and you can actually do it in less code than you can in C code.
Yeah.
And I think that's good. We now have the infrastructure in there. So, I think we've hit the tipping point. We'll start seeing new stuff in there. And we need to do that. I mean, there's mandates from governments that you can't use memory-unsafe languages like C in products.
Yeah.
And if I want to see Linux succeed, which I do, we're going to have to change, and I can say going forward, if you want to write in Rust, you can write in Rust. Now, that being said, we still have 40 million lines of C code.
Yeah.
So, we have some very, very good developers out there working on mitigating the problems we have in C. We now have bounds checking for our stuff. We now have other, we call them seat belts and airbags, that protect your C code from doing stupid things, and we've been working with the compiler authors to add new extensions to C and make things safer in C code, because we want to protect the code that we have today, because you're not going to rewrite code in Rust. Don't worry about that.
Google famously published something recently saying, over the past couple years we've written our new code in Rust and we got overwhelmingly more secure, because we didn't touch the old code, and bugs degrade over time. There's still going to be bugs in the older stuff, but most bugs happen in your new code, not in your old code.
That's awesome. I'm sensing you're excited about Rust, and it's also just nice to see the evolution.
Yeah, it's evolution. And see what happens. And if it fails tomorrow, we can rip it out and what up? But we have developers willing to do this work for us.
Yeah.
It's not intruding on other people's stuff.
Well, then I think it does go back to what you said earlier, as I understand that a big part of Linux is, like, show the work. Like, if it works. And same thing, you know, it sounds like that's how Rust started, and it's also how it's progressing. People are showing that it works. So, they're proving that it works, it solves their problem.
Yeah.
It's maybe even better for them, and then, you know, step by step.
Yeah, like people say, well, why not Zig or Hare? Those are other good languages. And, like, that's great, but nobody's proposed it.
Yeah.
[laughter]
Yeah, if they want to do that. And fair, I think those developers who work on those languages don't care about Linux, which is fine. They don't have to.
Article published
