Will 2020 Be The Year Of Rust In The Linux Kernel?

One problem with modern programming languages is the reach their overly enthusiastic early adopters have nowadays thanks to the internet. As a result, everyone else’s first encounter with them are oftentimes some crude, fanboyish endeavors to rewrite every single established software project in that shiny new language — just because — which may leave an off-putting taste behind. However, Rust certainly seems to have outgrown this state by now, and with its rising popularity within the general developer population, it’s safe to say it will stick around. Will it fully replace C one day? Probably not, but there’s a big chance for coexistence, and [Nick Desaulniers] got the ball rolling for that within the Linux kernel.

Now, before you storm off pledging your allegiance to C by finding a new operating system: nothing is happening yet. [Nick] simply tested the waters for a possible future of Rust within the Linux kernel code base, which is something he’s planning to bring up for discussion in this year’s Linux Plumbers Conference — the annual kernel developer gathering. The interesting part is [Linus Torvalds]’s respone on the LKML thread, which leaves everyone hoping for a hearty signature Rust rant akin to his C++ one disappointed. Instead, his main concern is that a soft and optional introduction of the support in the build system would leave possible bugs hidden, and therefore should be automatically enabled if a Rust compiler is present — essentially implying that he seems otherwise on board.

We’ll see what comes of it, but with Rust language team lead [Josh Triplett] stating that enhancements benefiting and advancing a kernel integration are certainly imaginable for Rust itself, we might see interesting collaborations coming up in the near future. If you don’t want to wait for that and use Rust already today in a user-land driver, check out this 35c3 talk. And if that doesn’t go far enough for you, here’s a whole (non-Linux) kernel written in Rust.

54 thoughts on “Will 2020 Be The Year Of Rust In The Linux Kernel?

  1. Rust is one of the few modern languages that has a real chance at replacing C for kernel level stuff. Getting use in a real world environment like the Linux kernel will be good for the language, too. Should be interesting to see what happens.

    1. Every argument they made in the article could also be applied to JavaScript, C#, and even PHP,

      GNU C will be likely be around 107 years from now with all of its language specific features and known problems.

      Why not take awesomer Rust and create a better new kernel to compete with Linux and BSD. Oh right, when it comes to real deployments it offers 5 small benefits and thousands of higher risk unknown feature fialure modes. Expect a fork if this naive option passes into the main branch, as few senior people will fall for the viral marketing.

      Rust still can’t even maintain its own package properly, and here we are half a decade later considering adding it to the kernel to satisfy some snowflake;s whim. If Linus Torvalds is tired of saying No to these people, than hire an assistant to be the manager for your team.

        1. “Argument” is a valid English word. Simplistic version:
          Rust people want a kernel. Rust people can’t get Rust to do that. They try, and their kernel doesn’t work.
          Rust people change their mind, they want to take a working kernel, add Rust, and break existing kernel. They hope all others will blame existing kernel instead of blaming Rust.
          Most all other people do not want to be involved with that.

          1. That’s utter nonsense. Rust in the kernel makes a ton of sense for drivers, for instance, especially for custom or not highly used drivers where the authors might not have a ton of experience and wouldn’t be maintained well.

            There are very good reasons why Rust is a solid alternative for writing kernel code, and languages like C++, go, Haskell, Ada, etc. aren’t, and to understand, you actually need to understand how those languages work at machine level. C++’s exceptions cause stack unwinding, which is super-bad for Linux. Garbage collection causes actions to happen out of the blue and unrepeatably, which again, super-bad. Of course you can build kernels that manage those problems. Building a kernel that runs *everywhere* and manages those problems is a huge task, which is why I said “super-bad for Linux.”

            Really, the only worry with Rust at this point is that it’s young. From a language standpoint it’s one of the most kernel-compatible languages out there, which is why there’s a conversation going on about it.

    2. C has really stood the tests of time rather well. You look at languages like C# and to some extent C++, where there’s the new way of doing things, the old way of doing things, and the old-old way of doing things. It’s like having to learn three languages to read C# code and understand how each successive revision of the language is used. C has been remarkably stable and reads nearly the same today as it did back in its 1970s origins. It fulfills the UNIX philosophy of doing a few simple things well which can be combined to build arbitrarily complex programs.

      If Rust goes down the path of layering on syntactic sugar every 5 years, then its long term value as a systems language will diminish in my view. If it focuses on stability, performance, and evolves with (but not abstract away) the bare metal (e.g. SIMD, async, multiprocessing, cache hierarchy), then it could deliver real value.

  2. I personally think we should wait a few years and see where Rust goes before committing to it. Currently you can’t even use apt/dnf/etc. to install it for example. The preferred way is using curl with a bunch of parameters…. To me that means it isn’t quite ready for ‘main stream’ yet unlike ‘C’. Give it a few years to mature. Who knows by then there might be another ‘next best wonderful, super-duper’ language that is the rage that everyone wants to jump to and Rust is left to rust in the shadows. Meanwhile ‘C’ will just keep getting the work done at a nice low level.

    1. Exactly. I completely agree. I understand these people: C is boring and not as exciting as Rust. But being boring also means a lot of stability. The compilers are optimized, people are comfortable with it and they know their tools. First appearance of Rust was in 2010 and the first stable version in 2015. It’s a young project and it should get treated like it. Adding another language to the Linux kernel and writing drivers in it is a big step.

      1. “means a lot of stability” Yeah that’s why gcc gets a bug-fix release every few months. And let’s not forget the many efforts to fork gcc due to its stability issues.

        “people are comfortable with it” thousands and thousands of security CVE reports would indicate otherwise, NOBODY is “comfortable” writing C code, EVERY human fails.

        The reality-distortion field is STRONG in this one.

          1. Let’s start with the bugs that don’t happen in Rust because they are caught in the compiler.

            That would probably eliminate about 75% of the CVEs, and save untold millions of people from data loss.

            Is this comparison good enough?

    2. Well said. I tend to agree, however doing a quick check just now on my Fedora 30 system, I see rust packages available to be installed via dnf, so things aren’t quite as you say. I would like to see an unemotional discussion of the pros (and cons) of using Rust versus C. People are always charmed by the latest cool thing, and that would not carry the day for me.

      1. So the plain old argument of the borrow checker, guaranteed safety, and zero cost abstractions could be made but the coolest thing I’ve seen the Rust teams point to and say “hey we did this to make ourselves useful” was that they included the `unsafe{}` escape that allows you to just write C code.

        I personally don’t like the naming “unsafe”. it should be named more like “trust_me” in that it doesn’t do any of the ownership checks so you need to write good C code in there.

        The reason I think it’s so compelling is the same reason it’s compelling in C. Back before C was king, everyone used assembly. It was only when the C standard said “You know what? Go ahead and do it in assembly if C doesn’t have what you’re looking for”, that the old hat assembly-or-die crowd gave it a serious look.

        If nothing else, their community is well set up. While they do receive funding from Mozilla, they have no say in what makes it in the standard. Make an RFC and go through the proper channels like everyone else. (I’m looking at you Go)… There’s a wide variety of working groups that do everything from embedded, to WASM. Speaking of, their HAL on embedded is a really neat idea I hadn’t heard of.

        I would also have to say something about their Async story. Man that’s cool. Memory safe, race condition-less async streams built into the language as a first class citizen.

        1. No, “unsafe” does not disable ownership checks. It even says in chapter 19 of doc/book: “It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust’s safety checks”.

          Here have a read: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html

          Or if you prefer code, watch the borrow checker complain inside an unsafe block: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=43b45685e42803319522bfd67bfa919a

          For some reason that stuff about Rust’s unsafe propagates here in Hackaday. We shouldn’t be coding based on hearsay.

          1. So I read it, and that passage says:

            “Those superpowers include the ability to:

            * Dereference a raw pointer
            * Call an unsafe function or method
            * Access or modify a mutable static variable
            * Implement an unsafe trait
            * Access fields of unions

            “[…] The unsafe keyword only gives you access to these five features that are then not checked by the compiler for memory safety. […] the intent is that as the programmer, you’ll ensure the code inside an unsafe block will access memory in a valid way.”

            If the only protection for dereferencing a raw pointer is the honor system, well, that sounds like C.

          2. @Skeptic,

            C only has a raw pointer, Rust have other pointer types:

            1) Reference – pointers to local or static variables
            2) Box – analogous to a C++ unique pointer (e.g. RAII malloc’ed pointer)
            3) NonNull – well.. a non-null raw pointer

            Those are never null. But you can wrap them with an Option to represent null pointers at no memory footprint cost. Compile time and runtime propagating null checks (via deconstructing an Option) gives Rust and edge even on raw pointers IMO. Microsoft has an equivalent in SAL annotations but who uses that? Not even MS themselves do.

            One use of unsafe is to convert raw pointers to those other pointer types in a marked (with “unsafe”) section of code so you have an easier time finding the source of your segfaults. Whatever lifetime and mutability you set there gets enforced by the compiler in the rest of your code.

      2. I stand corrected. Thanks. When I searched for ‘how to’ install Rust, dnf/apt never popped up as a method. Still I will stand by the rest of my comment :) .

        I installed it via curl . Even bought a book (yes, I still like to learn from a book ;) ) to help me get a handle on the language. I certainly didn’t see it as a ‘this is the final say on languages’ and a must learn though.

      1. There are pages and pages of non-standard features in gcc. gcc programs are not portable from one version of gcc to the next. gcc programs cannot be compiled with any other compiler without modification. What the F are you talking about?

        1. I believe he is talking about ‘standardization’ . ISO/IEC 9899:2018 for example. There will always be non-standard features added to any compiler, but all ‘C’ compilers should conform to the ‘standard’.

  3. I don’t get it. Don’t get me wrong. Rust is a nice language, no doubt. But there is a whole debate over unsafe for a good reason. At some point people tend to use raw pointer again, because of performance issues. Yes, it is way better than in other high level languages, but it is still there. Especially compared to C. The OS and especially the kernel should be as small as possible. The Linux kernel needs to run on very small devices. Some people are even running it on microcontroller. I don’t want to see a situation where you are not able to compile the kernel to these kind of devices anymore, because the rust compiler is not able to compile it for this architecture. They just overcome all the issues they had with embedded rust. I don’t understand why the Linux kernel needs any changes. You can write your apps, if you want to. Adding Rust to the Linux kernel in order to write drivers in it would just lead to a mess of different code basis. Not sure, if this is a good idea. Maybe when Rust gets older and stable. At the moment it is still a young project and the track record for it is still very short.

    1. Rust can often generate faster code than C, because it can skip emitting runtime checks for things it’s proved are invariant. It does more work at compile time so it can do less at runtime. Talking about needing “raw pointers for performance” indicates a basic misunderstanding of what’s going on.

      Why do you as a user get to dictate what a person writes their code in? It’s the choice of the person who is actually doing the hard work. If you don’t like it, you can write your own C driver instead and get that accepted instead.

      1. “Why do you as a user get to dictate what a person writes their code in?”

        It isn’t dictating. When I go to compile your code and it fails because rust doesn’t have a compiler for the system I’m using, your code becomes “not a valid option”
        We are not demanding you do anything to get that code to compile.
        But when your code won’t compile, this does not remove the users need for the software. We will simply fill that need with something else.

        Frankly it is amazing you hold the user at fault for that.

        1. Yes it absolutely is. If you want something unusual for your own needs, it’s up to *you* to do the work, not demand that everyone else should have already done it for you.

    2. Hell if you feel like you need to use raw pointer for performance reasons then you are doing something extremely wrong. Even on micro-controllers raw pointer belong to the lowest of low level libraries in the kernel itself.

      But Rust specifically on micro-controllers is not for faint hearted. It requires you to think absolutely completely different than in C. But then result is like fastest C code checked by static analyzer.

      1. So, if this is true, why should you start mixing C and Rust in the kernel then? How about just rewriting the kernel in Rust or creating your own kernel in Rust then? And then the bigger question: Is it really worth it?
        About the performance: The tests I have seen so far showed that Rust was always a little bit slower.
        So, if we start adopting Rust for driver and higher level in the kernel, what should you stop from adopting other languages as well? Some people talked about Zig. I have no idea about it, but maybe it is as good as Rust or even better. So then you start adapting a lot of different languages. I am not sure, if this is a good idea. Stick to C, it works it is great with well known issues. Write your application in Rust, if you want to.

        1. Those tests are usually best effort C and no to negative effort Rust :D Btw. sometimes it is worth to compare disassembly directly. I’ve done that several times on ARMv7E-M architecture.
          Another thing is that those test usually compare C compiled by GCC with Rust compiled by Rust+LLVM.

          If you compare C compiled by GCC with C compiled by Clang+LLVM you sometimes get substantial differences sometimes in favor of GCC and sometimes in favor of Clang+LLVM heavily dependent on a specific problem AND on compile parameters.

          “Is it really worth it?” & “what should you stop from adopting other languages as well”:

          Idealist in me says no and nothing. Explained: We should ditch stupid Linux and go full Rust microkernel while also adopting any reasonable languages for modules/microservices.

          Realists it me says: Hell I need the opensource AMDGPU driver so I can play with GPGPU and also have such little things like working displays on my PC. So let allow if not Rust then some other language to Linux kernel that have self/this syntax abstraction in meantime… Object-oriented programming in C is very painful to read.

          1. “We should ditch stupid Linux and go full Rust microkernel while also adopting any reasonable languages for modules/microservices.”
            I wouldn’t say stupid Linux, but I agree with the microkernel part. I contribute to RIOT OS and microkernels are just better. While I agree we already see how long this takes for Hurd. It’s not that simple to rewrite a whole kernel with all of its drivers. I mean, they could just write a microkernel and take Linux as base for it. So basically a fork.

            “Object-oriented programming in C is very painful to read.”
            Tried it and I wouldn’t recommend it.

        2. “So, if this is true, why should you start mixing C and Rust in the kernel then?”

          Okay. So the first thing to clarify is “what is the kernel?” By “in the kernel” do you mean part of the memory management/system call handling/prioritization/etc. – the base code that needs to run everywhere? What about specialized drivers for hardware that exists in order(1000) quantities (or less)? What about modules used mainly for research purposes, like certain filesystems? Does that still count as “part of the kernel” even if less than 1 ppm of the users of the kernel ever compile it?

          “what should you stop from adopting other languages as well?”

          Because Rust is one of the most C compatible languages out there. Being “compatible with C” doesn’t mean it *looks* like C. There are good machine-level reasons why other languages aren’t as easy to integrate.

        3. Zig appears to be a toy language with virtually no user or developer base…. Rust is a very widely used and popular systems programming language, and pretty much the only one that is as good as C performance wise and better in many ways. There are already very large projects written entirely in rust.

          No language is going to make it into the kernel without it at least showing up on the kernel developers radar, Zig doesn’t seem to meet that criteria.

  4. Rust has some serious issues. The primary issue is that there is no formal specification of what Rust is and as a result there is only one compiler and they can break all your code at will. The secondary issue is portability because while Rust has been ported to plenty of platforms, it has minimal or non-existent support for platforms it deems “experimental” which is everything that isn’t x86 or ARM.

    1. I see the platforms also as a big issue. Maybe most machines use ARM, x86 or x64 these days. But when I look at Microcontroller and embedded platforms, there is still a lot of MIPS etc. And we are just getting RISC-V. C is old, boring and you can compile it to every existing platform.

  5. I thought this was going to be about putting a compiler or interpreter into the kernel, not using the language to write the kernel.

    But that was just from the title.

    1. A huge source of problems in the kernel is writing device drivers for poorly documented and/or buggy hardware.

      If your specification is not fully known, you can’t have formal verification.

      1. That would only mean the specification is a work in progress and that the verification against the current spec may succeed while not working in practice. It’d still be an improvement and would still be formally verified.

    2. Well actually Rust’s compiler (non-optionally) does what in other languages do optional static analyzers!
      E.g. anything that looks like Rust code with a possibility of dangling reference is actually not Rust language but an uncompillable thing.

    3. The problem is that you have to write a specification…. Rust just enforces correctness rather than requiring you to define what correct is by imposing a model that allows that, and as Rust has developed many of the restrictions of that model have been relaxed as the compiler has matured.

  6. I’d like the idea of something like DLang in BetterC mode (garbage-collection turned off, or you can use custom garbage-collection now instead)
    Although I don’t think it’s gotten enough support yet to be a contender

  7. No offense, but I get a bit the impression the Linux Kernel is chosen because of the accolades that would come with it, not because it is actually a particularly amenable codebase for using Rust.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.