|
|
Log in / Subscribe / Register

Rustaceans at the border

Rustaceans at the border

Posted Apr 14, 2022 19:24 UTC (Thu) by rvolgers (guest, #63218)
Parent article: Rustaceans at the border

> "Async Rust" knows nothing about kernel threads or how context switching is done in the kernel, for example. Kernel code must be extremely careful in how it allocates memory, must not use floating-point arithmetic, cannot store large data structures on the stack, and cannot use unbounded recursion,

The Rust response to this would probably be "can't we just... solve that?"

Various embedded Rust folks have been doing work on things like static stack usage analysis. Tight stack requirements are not unique to the Linux kernel by any means, it is clearly desirable to have insight and control over that.

And as for memory allocation, again, people write Rust code which has no support for memory allocation at all, using libraries which are on crates.io. And they're not always super custom libraries, sometimes it's literally just a matter of enabling the "no_std" feature flag, and you can use a bog-standard Rust library (with a somewhat more limited API, of course).

More complex things like interrupt context seem more likely to remain "here be dragons" territory (just like signal handlers are, to some degree, in userspace). But Rust is hardly unique in that; not all kernel C functionality is safe to use there either.

TLDR: Some of the arguments being used smack of prejudice against Rust ecosystem libraries as being by definition userland-focused. Many are, but many are not, and some adapt well to either use case.


to post comments

Rustaceans at the border

Posted Apr 14, 2022 19:47 UTC (Thu) by atnot (guest, #124910) [Link]

> sometimes it's literally just a matter of enabling the "no_std" feature flag, and you can use a bog-standard Rust library

To add to that, some of the requested libraries like pin_project and serde to my knowledge do not even really exist at runtime at all. There are a lot of utility crates like that which contain a bunch of fancy macro and type definitions, at most a few lines of which will actually end up in the final binary.

Rustaceans at the border

Posted Apr 14, 2022 22:13 UTC (Thu) by farnz (subscriber, #17727) [Link]

On top of that, this is a case where a perfect solution isn't needed; if automation can permit 70% of the crates that would work well in kernel space into the kernel, and provide a way for a human to audit and certify the remaining 30% of those that would work as accepted for kernel use, that's a good outcome. Which, in turn, means that a conservative approximation is good enough - rejecting 90% of crates as "not kernel compatible for $reason", accepting 7% as "kernel compatible", and leaving 3% as "not sure - needs a human involved" would work just fine as a solution.

Rustaceans at the border

Posted Apr 14, 2022 22:33 UTC (Thu) by ssokolow (guest, #94568) [Link] (5 responses)

sometimes it's literally just a matter of enabling the "no_std" feature flag, and you can use a bog-standard Rust library (with a somewhat more limited API, of course).

Rust feature flags are additive, so the convention is to declare an on-by-default feature flag named std which toggles the no_std attribute.

(no_std being equivalent to GCC's -nostdlib.)

Rustaceans at the border

Posted Apr 15, 2022 0:05 UTC (Fri) by tialaramex (subscriber, #21167) [Link] (4 responses)

Note that -nostdlib is getting rid of almost everything, whereas Rust's no_std only gets rid of stuff from std itself (much of what you think of as Rust's standard library was only re-exported from std and actually lives in core or alloc).

So e.g. suppose you've got a slice (maybe an array, but however you got it, some contiguous memory) of Things and you'd like to sort them. In C without the standard library you're out of luck, code it yourself, but in Rust lacking std only means you don't have a nice stable allocating merge sort, you do still get a perfectly usable (albeit not always trivially what you needed) in-place unstable sort.

https://rust-for-linux.github.io/docs/core/primitive.slice.html#method.sort_unstable

When C was invented such things would be too heavy, but today Rust's compiler and linker are certainly smart enough that if you never actually perform sort_unstable the code to implement it is omitted from your binary so the "price" of Rust's more comprehensive library is only that the documentation is a little larger and for that price you avoid the unsettlingly common (even in Linux) discovery that six people have re-implemented some useful idea, meaning the kernel carries not one but six copies of the code, and worse at least one of them is actually faulty.

Rustaceans at the border

Posted Apr 15, 2022 23:46 UTC (Fri) by Hello71 (guest, #103412) [Link] (3 responses)

> When C was invented such things would be too heavy, but today Rust's compiler and linker are certainly smart enough that if you never actually perform sort_unstable the code to implement it is omitted from your binary

afaik, unix linkers have pruned unnecessary object files from the final link for basically as long as unix has existed. this is the origin of needing to specify -l flags in dependency order. this doesn't help with dynamic linking, but rust has no magic pixie dust there either.

Rustaceans at the border

Posted Apr 16, 2022 1:00 UTC (Sat) by nybble41 (subscriber, #55106) [Link] (2 responses)

> unix linkers have pruned unnecessary object files from the final link for basically as long as unix has existed

Yes, but Rust goes farther. It doesn't just prune unused object files as a whole but individual functions, global data, trait implementations, and even code paths, taking advantage of static analysis across module boundaries. The closest equivalent in C would be link-time optimization, which is relatively new and not enabled by default.

Rustaceans at the border

Posted Apr 16, 2022 11:26 UTC (Sat) by smurf (subscriber, #17840) [Link] (1 responses)

Any C compiler worth its salt already can put each function into its own section, which the linker then skips if it's not referenced. This scheme has been supported by gcc/ld since, umm, whenever. It's hardly as comprehensive as LTO but gets the job done well enough for the kernel and, frankly, most other codebases that aren't heavily obfuscated C++.

Rustaceans at the border

Posted Apr 17, 2022 2:48 UTC (Sun) by willy (subscriber, #9762) [Link]

You might want to check whether CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is set in your kernel before making such confident assertions.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds