I have a hard time seeing this happen. Rust has most of the same properties which prevent C++'s inclusion in-tree. (Look up Linus' opinions on C++ if you aren't already familiar.)
Further, as far as I can tell, Rust currently lacks mainline GCC support which I believe will be a blocker.
Here's Linus's answer inside the thread, which is quite positive:
From: Linus Torvalds @ 2020-07-10 23:54 UTC (permalink / raw)
To: Josh Triplett
Cc: Christian Brauner, Nick Desaulniers, alex.gaynor, Greg KH,
geofft, jbaublitz, Masahiro Yamada, Miguel Ojeda, Steven Rostedt,
LKML, clang-built-linux, Kees Cook
On Fri, Jul 10, 2020 at 3:59 PM Josh Triplett <josh@joshtriplett.org> wrote:
>
> As I recall, Greg's biggest condition for initial introduction of this
> was to do the same kind of "turn this Kconfig option on and turn an
> option under it off" trick that LTO uses, so that neither "make
> allnoconfig" nor "make allyesconfig" would require Rust until we've had
> plenty of time to experiment with it.
No, please make it a "is rust available" automatic config option. The
exact same way we already do the compiler versions and check for
various availability of compiler flags at config time.
because I _don't_ want us to be in the situation where any new rust
support isn't even build-tested by default.
Quite the reverse. I'd want the first rust driver (or whatever) to be
introduced in such a simple format that failures will be obvious and
simple.
The _worst_ situation to be in is that s (small) group of people start
testing their very special situation, and do bad and crazy things
because "nobody else cares, it's hidden".
> "C is still one of the top 10 languages," answered Torvalds. However, he said that for things "not very central to the kernel itself", like drivers, the kernel team is looking at "having interfaces to do those, for example, in Rust... I'm convinced it's going to happen. It might not be Rust. But it is going to happen that we will have different models for writing these kinds of things, and C won't be the only one."
The thing is the kernel is kinda hurting for maintainers and opening up the path for the next generation of systems programmers (most of whom don't want to touch C any more than they have to) has to be something Linus is more likely to prioritize than in previous decades.
> We do not have enough maintainers. We do have a lot of people who write code, we have a fair number of maintainers, but... it's hard to find people who really look at other people's code and funnel that code upstream all the way, eventually, to my tree... It is one of the main issues we have.
If I read this correctly, they have a lot of contributors, but few people willing to follow through with the code so it gets all the way up to Linus' tree. I don't see how rust would really help there.
It could be. Maybe there will not be more reviewers, but the process of reviewing could be faster. For example, in the kernel there are inline functions, which accept a constant (known at compile time) integer argument, and they make a switch or loop over that integer. The trick is to force compiler to inline function and to throw away most of switch's cases, or unroll loop completely, or make some other optimizations based on knowledge of the passed integer value.
Such a functions are exported to a public kernel API sometimes. So any kernel developer could call them. It make unavoidable a mistake of a programmer, when some of those functions was called with an unknown at compile time integer value. It is not a bug as it is, code would compile and work nevertheless, code would be bigger that it could be, maybe slower, that's all. But reviewer should be finding such a misuse of API.
It is just one example, linux kernel uses a lot of tricks and exposes it via APIs, reviewer must be aware of all of them and to check everything by itself.
Compare it with Rust. In rust one can encode a lot more limits on the right use of an API than in C. Encode and enforce. Even when rust sometimes cannot do it, rust have nice macros, instead of C's macro-horror. So a lot of mistakes that could be made with C, could be avoided with Rust. So it would be easy to review code, it would take less time from a reviewer to review code.
Driver code has a lot of concurrency and is very unforgiving for any mishandling of memory. If you want to write good kernel code in C you need to have a strong mental model of who owns what, who does what on whom, what can interrupt, what can be interrupted, what shouldn't be interrupted etc...
Having the compiler enforce some of these invariants for you might well end up making writing the code easier, not harder. Rust has a steep learning curve, that's absolutely true, but in my experience I feel a lot more at ease writing complicated parallel code with complicated ownership models in Rust than in C.
C is a trickster: in practice if you want to write correct C code you have to use a memory model very similar to that of Rust, the main difference being that Rust forces you to do it (mostly) right whereas C will gladly let you write completely broken code.
Really, you should rarely be using raw memory barriers even in C, IMO. The C11/C++11 atomics model (which Rust also uses) is substantially nicer. Though, unfortunately, still extremely tricky to get right.
Writing safe C and C++ is even much more difficult than writing Rust code (especially with many developers). And when you are writing kernel code, both safety and performance are crucial.
The problem seems to be to find people who do not just want to write code, but do the administrative parts:
"We do not have enough maintainers. We do have a lot of people who write code, we have a fair number of maintainers, but... it's hard to find people who really look at other people's code and funnel that code upstream all the way, eventually, to my tree... It is one of the main issues we have."
Actually I think the answer is yes, as Rust is much stricter to the person who's contributing the code. If I was asked to review another person's code, I would much prefer reviewing Rust code, as I would be able to concentrate on the logic and the efficiency of the code instead of potential low level mistakes.
The code smell in Rust is usually marked with ,,unsafe'', Boxing / reference counters, or dynamic behaviour, which is very easy to search for.
The amount of extra automatic memory management is often a good indicator of not well thought out data structures (although of course they are not always needed).
- do I really need threads when I can share non-mutable messages or copies of same? Maybe (speed, throughput). Maybe not. Depends. What's clear is I need choice.
- how do I get correctness? Rust maybe checks for index bounds. But in C++ I just relegate that to a library and voila std::string/vector.
I am concerned for Rust: placing too much emphasis on correctness through language alone seems to be a weak point. Correctness through libraries and augmenting with formal tools seems like a much stronger solution.
Despite its ubiquity, the Linux kernel is not actually the golden standard for safety or performance. Not even for code quality. Ada remains the language of choice in areas where safety is actually crucial. Rust isn't going to take it's spot either.
I am inclined to agree. By the way: when I first read about Rust and its "safety features" that make it appealing to people, the first programming language that came to mind was Ada. I suppose it lacks the hype (and consequently a vibrant ecosystem, IMO) and people hold absurd misconceptions of the language[1]. :/ I am trying my best to dissipate those misconceptions on Hacker News; hopefully it does not count as shilling. :P
If any of you reading this comment is interested, you may want to check out my previous comments regarding Ada.[2]
By the way, just to be on topic: I found Linus' opinion on Ada vs Rust here: https://news.ycombinator.com/item?id=20838125. He said "We've had the system people who used Modula-2 or Ada, and I have to say Rust looks a lot better than either of those two disasters.". That is all though, he does not get into explaining why he believes Ada to be a disaster. Again, "I do not see any reasons given for why he considers Ada a disaster. Cannot really do much with this opinion as it is."
With Ada you can't use dynamic memory allocation and pointers safely, unless you buy into SPARK, which is heavier-weight than Rust (and also post-dates Rust).
> Standard Ada supports safe use of pointers (“access types” in Ada) via strongtype checking, but safety is guaranteed only for programs where there is no explicit deallocation of pointed-to objects
This validates "With Ada you can't use dynamic memory allocation and pointers safely, unless you buy into SPARK". (GC not relevant in this context.)
> In this work, we propose a restricted form of pointers for Ada that is safe enough to be included in the SPARK subset. As our main contribution, we show how to adapt the ideas underlying the safe pointers from permission-based languages like Rust [3] or ParaSail [13]
This validates that the pointer support in SPARK "post-dates Rust".
"heavier-weight" is arguable. I'll withdraw that assertion. SPARK is definitely less expressive than Rust though; it doesn't have lifetime variables, and it doesn't allow borrows of stack values:
> The most notable one is that SPARK does not allow general access types. The reason is that we did not want to deal with accesses to variables defined on the stack and accessibility levels.
It's worth noting that Linus Torvalds does not write life-critical software. Take his opinions with a pinch of salt. He's made some of the most incredibly valuable contributions to computing, however this does not make him an authority on all things programming. He's anything but infallible.
Requiring certain classes of drivers, for example, to be written in Rust could be great for maintainers.
The person who submits the code has to do more work up front to satisfy the Rust compiler that there are no ownership issues, data races, etc. Maintainers have less work to do because, assuming the code compiles and does not use unsafe blocks, they can be confident the invariants promised by Rust hold. You have moved work from maintainers to submitters. (But you have also given submitters a way to get quicker, automated feedback on their work.)
I have used a bit of rust and c. I found rust significantly easier since the std lib contains a whole lot more useful stuff. And C is starting to get a bad rep like php and cobal have. The next generation of programmers probably won't bother with it and seek jobs using newer and better languages.
Rust in the kernel is not guaranteed to get stdlib. Running on bare metal is often done with `no_std`. Remembering how memory allocation in the kernel can happen in a multitude of ways, I'm not even sure the usual stdlib could be leveraged. Strings, for example, allocate memory implicitly.
That being said, apart from a good stdlib, I found Rust much easier than C due to a consistent type syntax, sum types, generics, traits, and the compiler hitting me on the head with lifetime errors.
Rust integrates easily with C because it's explicitly designed to fall back to the C ABI for external linkage. Whereas writing C++ with any C++-specific features (hence, any "Modern", guidelines-compliant C++ at all) brings its own bespoke ABI into the picture, that's supposed to be stable but really is not and that one can't easily interoperate with from C. That's a huge non-starter in kernel dev.
C compatibility is marked the same way, but it's not idiomatically used the same way in C++ and Rust. In C++, being C compatible means essentially writing C and for everything else you're expected to rely on the "not really stable" C++ ABI whereas Rust does not even try to give you a stable ABI between stuff that's not part of pretty much the same build. Despite that, you're free to mix C-like and Rustic code in the same crate because the crate is literally the translation unit in Rust.
ABI stability doesn't matter for the kernel since it doesn't have a stable ABI either. You can write a C++ core and C wrappers for C++ classes just fine, the same as what you do in Rust.
I’m a huge Rust fan, but this is a misrepresentation of C++. You can definitely use the vast majority of modern C++ features while also integrating with a C codebase (exotic control flow such as exceptions and coroutines are definitely dangerous, though).
Why would it require clang for the C components? The Rust compiler creates native libraries which can be linked to compilation units created by both clang and gcc, unless there's something special going on in the kernel that I'm not aware of.
Further, as far as I can tell, Rust currently lacks mainline GCC support which I believe will be a blocker.