|
|
Subscribe / Log in / New account

Rust heads into the kernel?

Rust heads into the kernel?

Posted Apr 21, 2021 22:59 UTC (Wed) by roc (subscriber, #30627)
In reply to: Rust heads into the kernel? by josh
Parent article: Rust heads into the kernel?

Won't you also want to make Result<T, Errno> a single machine word where T is u32 or even u63?


to post comments

Rust heads into the kernel?

Posted Apr 22, 2021 8:31 UTC (Thu) by pbonzini (subscriber, #60935) [Link]

It would be a bit more complicated by Rust being much more strict on integer casts. It means that you'd use usize in many places where C would use unsigned (or more likely, use an int that would always be positive).

Rust heads into the kernel?

Posted Apr 22, 2021 19:03 UTC (Thu) by josh (subscriber, #17465) [Link] (1 responses)

That's theoretically possible but would take either some more language work or some library work, beyond the language work we'd need to do to allow storing enums in the 0-4095 niche of pointers.

I'm assuming that you mean "a single machine word" on a 64-bit system, because on a 32-bit system you can't store a general u32 and something else in the same 32-bit word.

Rust, today, has the property that a type is always stored the same way no matter where you put it, even when taking advantage of niches and similar. That's important because if you have a Result<T, Errno>, if it's an Ok you can get a &T from it, and if it's an Err you can get a &Errno from it. So, that &Errno needs to actually reference a thing that looks like an Errno in memory, not something that's been tweaked to use different enum values.

That works fine for a reference or box or other type that cannot have a value in the range 0-4095 (once we have the ability to declare that "not in the first page of memory" niche). An Errno can use that niche.

However, if you have some type T that has a niche that isn't 0-4095 (random example: a "userspace pointer" that can't point into kernel memory but *can* potentially be 0-4095), such that T's valid values and Errno's valid values would overlap, you can't tweak the Errno's values to store them in T's niche. That would mean you couldn't get a valid reference to an Errno, because it needs translation before extracting it.

In the specific case of a u32, the easiest solution is just to let Rust store the u32 and the Errno alongside each other, and they should take up no more than a 64-bit word.

To solve the general case of niches that would require transforming the values of Errno when storing/extracting them, we could handle that in two ways, one at the library level or one at the language level:

At a library level, we could just have a dedicated type (not Result) that stores an Errno and another type, which *doesn't* let you get a &Errno from it, and instead only lets you get an Errno. (Errno itself is smaller than a machine word, so we might as well just use its value.) We could then teach that dedicated type to store the errno in the niche of the T, and re-extract it later. That would solve the specific problem, with some effort, but would require writing code specifically to handle that transformation.

Or, at a language level, we can add a concept of "types that you can't have a direct reference to", make a version of Errno with that attribute, and then allow such types to take advantage of arbitrary niches in other types. Because you can't have a reference to those types, they don't have to be stored in a way that looks exactly like they'd be stored if standalone. You'd typically use it for types that are so cheap to copy (because they're smaller than a machine word) that the inability to reference them isn't an issue.

That language-level approach is the kind of thing that you can teach the Rust language to do *once*, and then it can automatically do the kinds of optimizations that in C you'd have to manually manage in each data structure.

Rust heads into the kernel?

Posted Apr 23, 2021 0:43 UTC (Fri) by roc (subscriber, #30627) [Link]

I think there's actually a conundrum here. Someone is going to have to decide how much language and compiler work to do before you really push on Rust being used in the Linux kernel --- because before you do the latter, you will need to settle once and hopefully for all the idiomatic way to handle Errno results for various common T types.


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