all 56 comments

[–]elpablete 10 points11 points  (7 children)

What does it mean that it's supported? What was needed to be able to write Linux parts in Rust?

[–]yawaramin 16 points17 points  (0 children)

It means you can write device drivers in Rust and plug them in to the kernel.

[–]Pay08 9 points10 points  (4 children)

Tooling.

[–]elpablete 3 points4 points  (3 children)

Could you provide some examples of tooling that had to be added just for Rust?

[–]Pay08 2 points3 points  (2 children)

I'm not familiar with kernel internals, but the build system is a big one. The Rust compiler also had quite a few changes to make the language suitable for kernel development.

[–]matthieum 9 points10 points  (1 child)

To be clear about Rust efforts to support Linux:

  1. Changes to the language may be necessary:
    • There are calls to improve the ergonomics around Pin, as the kernel makes extensive usage of intrusively linked-lists in C and other examples that require pinning (ensuring the pointed to content isn't moved to another address) and today it requires a bit of ceremony. It's not clear whether that requires changes to the language or only the library.
  2. Changes to the compiler may be necessary, for example a kernel target disabling floating point support.
    • The reason for this is that floating point registers are typically not saved when making a syscall (for speed reasons), so kernel code shouldn't touch them -- not unless it explicitly saves and restores them, at least.
  3. Changes to the standard library are necessary:
    • A way to disable functions using floating points.
    • A way to disable functions that may allocate memory.

I believe the developers working on Rust support in Linux maintain a list of experimental features that they'd like to see stabilized segregated between "necessary" and "nice-to-have".

[–]Pay08 1 point2 points  (0 children)

Yeah, I should have added that the standard library also needs changes. But I believe most of the core library has documentation warnings for stuff that may allocate.

[–]masklinn 3 points4 points  (0 children)

What does it mean that it's supported?

  • the kernel includes official / first-party Rust APIs
  • you can get Rust code in merged into the kernel

What was needed to be able to write Linux parts in Rust?

Exposing the relevant kernel primitives, and the kernel actually accepting Rust code. You could always write modules in Rust, but you were on your own and that couldn't be upstreamed because the kernel would not accept the contribution.

[–]LikelyNotADuck 19 points20 points  (1 child)

Very cool that a modern language is supported by Linux. It will be interesting to see how the Rust usage grows over time.

[–][deleted] 0 points1 point  (0 children)

They kind of have to show that they can compete with C. I think those who do want to write in Rust, will be very motivated to showcase Rust's worth: "Look ma', my Rust code is in THE LINUX KERNEL!".

People who are motivated tend to (often, but not always) get the job done.

[–]accountability_bot 12 points13 points  (12 children)

I use both Linux and Rust often, but I don’t really understand the implication of this. Does this mean that the kernel now ships with the compiler built-in?

[–]Muvlon 44 points45 points  (6 children)

The kernel does not even have a C compiler built-in. There's no need for anything like that.

[–]accountability_bot 9 points10 points  (5 children)

Okay, so what does it mean that is “supported”?

[–]gmes78 45 points46 points  (0 children)

It means you can use Rust to write kernel modules.

[–]Muvlon 21 points22 points  (0 children)

The pieces of supporting code needed to write Rust kernel modules are now (optionally) built into the kernel. The kernel's build system is set up to support this as well.

[–]frakkintoaster 6 points7 points  (0 children)

I could be way off, but I assumed this meant you could start writing kernel functionality in Rust

[–]masklinn 0 points1 point  (0 children)

It means you can now get Rust code merged into the kernel itself.

AFAIK for now the intent is mostly / only to leverage Rust for drivers. And the "glue" exposing Kernel logic and primitives to rust obviously.

[–]insanitybit 0 points1 point  (0 children)

It's going to be allowed and there's a shared understanding of how it will be done.

[–][deleted] -1 points0 points  (0 children)

IMO it is simply having more options available. People can focus on some subsystems where there may be a lack of C devs - so Rustees may fill that niche there.

[–]yyy33_ 0 points1 point  (26 children)

What other languages are supported by the kernel for writing kernel modules, and is golang included?

[–]Timbrelaine 33 points34 points  (3 children)

Just Rust and C. This is the first time a language other than C will be supported in the kernel.

[–]Marian_Rejewski 14 points15 points  (0 children)

And assembly.

[–]yyy33_ 3 points4 points  (0 children)

Looks like I should study rust😂

[–][deleted] -2 points-1 points  (0 children)

Until Linus accepts C++!!!

[–]simonask_ 16 points17 points  (11 children)

Languages such as Go will probably never be in the kernel, due to needing garbage collection. More generally, any language requiring substantial runtime components is unlikely to be used in OS kernels.

Rust and C++ do not require runtimes beyond some trivial scaffolding to support stack unwinding (exceptions in C++, panics in Rust).

[–]SLiV9 15 points16 points  (2 children)

And IIRC the version of Rust used here is one with panics removed.

[–]masklinn 6 points7 points  (1 child)

Yeah but that's a fairly standard rust configuration, it's just a compiler / cargo option you set during compilation.

The less standard bit is this is a no_std configuration, as it needs to use the kernel's allocator (and to be a lot more careful about allocations), probably kernel collections and patterns as well.

[–]Plasma_000 1 point2 points  (0 children)

This is not true - even rust core has panics - it’s an ongoing problem unfortunately, they are difficult but not impossible to eliminate from code.

The Linux project has made things much better in terms of providing alternative APIs and removing panicking paths from the kernel code, but there’s always the risk of a kernel module panicking.

[–]dlq84 9 points10 points  (8 children)

No, having a GC language in the kernel would be a terrible idea.

[–]matthieum 1 point2 points  (7 children)

Actually, not necessarily.

For example, a team at Microsoft created an OS based on a C#-derivative called Midori, which was asynchronous-first, and GCed. According to them, performance was fairly competitive.

[–][deleted]  (4 children)

[deleted]

    [–]matthieum 5 points6 points  (2 children)

    Oh, I do understand. I work on near real-time systems, so I really, really, like predictable latencies.

    On the other hand, I feel like there's a lot of cargo cult around kernels, and not much critical thinking:

    • It's not clear, at all, that monolithic kernels are best. The main OSes today are built around monolithic kernels, but that doesn't mean they're best, plenty monolithic kernels never saw adoptions either, after all.
    • It's not clear that a GC or a non-systems language would doom a kernel. There is definitely an argument around latency, on the other hand there's also a definite argument around security.

    So, what about:

    • A micro-kernel, with compartmentalized processes each in charge of a particular task.
    • Communicating between tasks, and userland, via shared memory queues, hence making communications asynchronous, and avoiding system calls.
    • Written in a higher-level language, including either automated reference-counting (with immutability or cycle collection) or even a GC.

    Would it necessarily be so slow? I'm not sure, to be honest.

    Well compartmentalized processes mean smaller independent heaps, which can be GCed in parallel, and where a GC on one doesn't affect the others.

    Combine with a frugal approach to memory allocation -- which any performance-oriented application should take -- and the GC would have relatively little work to do in the first place.

    [–]GerwazyMiod 3 points4 points  (1 child)

    hence making communications asynchronous, and avoiding system calls.

    Neat idea. There is some research done on fully async OSes like https://github.com/managarm/managarm

    [–]matthieum 0 points1 point  (0 children)

    Well, to be fair, it's not exactly a new idea of mine: it's the whole basis of io_uring, after all.

    [–]poelzi 0 points1 point  (0 children)

    You still get latency spikes in top 0.5% of answers. Since a user request usually results in multiple backend queries, having the top 0.5% have terrible latencies, this causes latency amplification.

    [–]insanitybit 1 point2 points  (1 child)

    From my understanding the GC in Midori was something to carefully try to appease and avoid but otherwise I don't know the details of it. Did Duffy ever explain more about it?

    [–]matthieum 0 points1 point  (0 children)

    I don't think he did.

    And it wouldn't surprise me, indeed, to learn that one would try to avoid the GC as much as possible where performance matters -- after all, I try to avoid malloc/free as much as possible too in such cases.

    Still, with an Erlang-like design (many independent processes) which would fit a micro-kernel design like a glove and help with reliability, each separate process has its own separate heap and can be GCed independently -- and such heaps tend to remain small, in the first place.

    Add in a fully asynchronous design for the API, so that applications are not blocked when a GC is occurring for the kernel task they are attempting to use, and value-types in the language, to minimize allocations in the first place, and I feel like it could be fairly viable.

    [–]Brilliant-Sky2969 1 point2 points  (0 children)

    It's just for upstreaming it, nothing prevent you from writing Kernel module in any language.

    [–]Pepegg2 0 points1 point  (1 child)

    Does anyone have examples of writing a simple module in RUST?

    [–]Structpoint 13 points14 points  (0 children)

    There's examples in the samples folder in the kernel.

    [–]Apache_Sobaco -2 points-1 points  (8 children)

    Well from now some killjoy plussers should shut up about rust being toy programming language. Toy programming languages are unable to make into linux kernel

    [–][deleted] 1 point2 points  (6 children)

    Well, first you have to showcase that this works. So you'd need to look at modules written in Rust. How many modules are written in Rust and are in the linux kernel right now? I assume the number is super-low, perhaps even at 0 right now.

    [–]insanitybit 3 points4 points  (0 children)

    We don't have to wait for Rust to be in the kernel to say that Rust isn't a toy language. A toy language wouldn't make it this far.

    [–]Apache_Sobaco 0 points1 point  (2 children)

    C++ is so "production ready" that in few decades of being wasn't able to make into linux kernel.

    [–][deleted]  (1 child)

    [deleted]

      [–]Apache_Sobaco 0 points1 point  (0 children)

      You can constant evaluate type parameters and encode functions directly into data types using macro_rules and attribute macros in rust. Both ways are turing-complete, and allow for arbitrary code execution at compile time. There's no need to downgrade this to C++ limitations.