|
|
Subscribe / Log in / New account

Learning Rust

Learning Rust

Posted Feb 4, 2025 20:38 UTC (Tue) by Cyberax (✭ supporter ✭, #52523)
In reply to: Learning Rust by Trainninny
Parent article: Resistance to Rust abstractions for DMA mapping

> And unsafe can have undefined behavior/is not memory safe. And even a single instance of unsafe can require a whole Rust module to have to be vetted.

The `unsafe` in that driver is used for actual hardware interaction (reading registers, etc.). Linux Rust already has "safe" wrappers for almost all of them, so this driver can be rewritten in safe Rust. Once the DMA abstraction lands.


to post comments

Learning Rust

Posted Feb 4, 2025 21:28 UTC (Tue) by Trainninny (guest, #175745) [Link] (9 responses)

Interesting. I cannot ask you to make this guess, but, in case that you are willing to guess at a ballpark figure: How large a proportion of unsafe might Rust code in the Linux kernel on average potentially in theory have, if we assume a theoretical future in 5 years where everyone including all current maintainers write Rust in the Linux kernel?

Learning Rust

Posted Feb 4, 2025 23:27 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link] (8 responses)

I think that something simple like RTL-8139 (I loved that network card back in the day, it was a huge upgrade from RTL-8029) can be written without unsafe code entirely, using only safe abstractions. One stylistic choice that can matter a lot, is whether all the hardware interactions are marked as "unsafe".

More complicated drivers will have some unsafe code. Asahi Lina's DRM driver is probably a good approximation for it: https://github.com/AsahiLinux/linux/tree/gpu/rust-wip/dri...

Learning Rust

Posted Feb 5, 2025 2:07 UTC (Wed) by Trainninny (guest, #175745) [Link] (7 responses)

More unsafe than I hoped for. More than a 100 occurrences, spread out over most or all the files. Some of the blocks are 5 or more lines. And for some kinds of unsafe, the whole module has to be vetted, not only the unsafe block.

https://doc.rust-lang.org/nomicon/working-with-unsafe.html

>Because it relies on invariants of a struct field, this unsafe code does more than pollute a whole function: it pollutes a whole module. Generally, the only bullet-proof way to limit the scope of unsafe code is at the module boundary with privacy.

Anyone developing or maintaining those files may have to have a very good understanding of unsafe, or at least good enough to know what parts of the code outside the unsafe blocks can affect the correctness of the unsafe blocks. Are there other options for learning unsafe outside of Rustonomicon or blog posts?

If unsafe in that folder tree had been confined to one or two files, in its own small module, it might have been nicer.

Learning Rust

Posted Feb 5, 2025 3:49 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (4 responses)

> More unsafe than I hoped for. More than a 100 occurrences, spread out over most or all the files. Some of the blocks are 5 or more lines. And for some kinds of unsafe, the whole module has to be vetted, not only the unsafe block.

No. As long as `unsafe` blocks uphold the invariants, they are safe globally. And if you violate invariants inside the `unsafe` blocks, then the effect goes far beyond the module.

Learning Rust

Posted Feb 5, 2025 4:12 UTC (Wed) by Trainninny (guest, #175745) [Link] (3 responses)

>No. As long as `unsafe` blocks uphold the invariants, they are safe globally. And if you violate invariants inside the `unsafe` blocks, then the effect goes far beyond the module.

Is that consistent with the following?

https://doc.rust-lang.org/nomicon/working-with-unsafe.html

>Because it relies on invariants of a struct field, this unsafe code does more than pollute a whole function: it pollutes a whole module. Generally, the only bullet-proof way to limit the scope of unsafe code is at the module boundary with privacy.

Basically, the code in the unsafe block relies on code outside the unsafe block being correct in some regards to be memory safe/not have undefined behavior. And thus requiring vetting of much more than the unsafe block.

Did I misunderstand the Rustonomicon? Or is the Rustonomicon wrong here?

Learning Rust

Posted Feb 5, 2025 5:29 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (2 responses)

The Rust Book is unsound. A mere module boundary can not isolate the unsoundness of bad unsafe code.

Learning Rust

Posted Feb 5, 2025 5:36 UTC (Wed) by Trainninny (guest, #175745) [Link]

Is the point of https://doc.rust-lang.org/nomicon/working-with-unsafe.html not more that:

1: If you have a module with some unsafe code in it, and whether that unsafe code is memory safe/has no undefined behavior, or not, relies on code outside that unsafe block, for instance mutable state;

2: And that mutable state's visibility has been limited to the module;

3: Then it is only the module that needs to be vetted.

This can still be a lot more code that needs to be vetted than just the unsafe block, but at least not more than outside the module, due to usage of visibility.

Learning Rust

Posted Feb 5, 2025 9:46 UTC (Wed) by farnz (subscriber, #17727) [Link]

The Nomicon is talking about something different; if you have an invariant that unsafe code depends upon, but that can be broken by the actions of safe code, that's not OK unless you can guarantee that you have audited all of the safe code that could break the invariant. A module boundary provides that guarantee - if the only things that can break the invariant are in the same module as the unsafe code, then you can guarantee that you have audited all of the safe code that can break the invariant.

The canonical example of this is alloc::vec::Vec; safe code inside the alloc::raw_vec and alloc::vec modules can break safety guarantees (you can inline Vec::set_len to safe code in alloc::vec, for example, which breaks invariants that unsafe code depends upon). But this is considered acceptable (despite the unsafe code being unsound if the safe code breaks the invariant), because all of the code that can break the invariants must, definitionally, be in the same module as the unsafe code that depends on those invariants holding.

Learning Rust

Posted Feb 7, 2025 0:31 UTC (Fri) by moltonel (subscriber, #45207) [Link] (1 responses)

See the author's breakdow of unsafe uses: https://www.reddit.com/r/rust/comments/1f5qbvu/comment/lk... Apparently most of it is relatively simple, and certainly not the rare "harder than C++" kind.

You shouldn't worry too much about the use of unsafe in kernel code: it's a small number of lines that need closer scrutiny, but it's not that hard. Writing that driver in C would have been much more error-prone.

Learning Rust

Posted Feb 7, 2025 8:09 UTC (Fri) by smurf (subscriber, #17840) [Link]

Also see https://vt.social/@lina/113056457969145576 for a somewhat more verbose exposition of AsahiLina's experience with Rust vs. The Kernel.

Bottom line: Rust wins. And frankly the proof is right there, because given the complexity of what she and her collaborators have to work with, IMHO she couldn't have done the job with C (and neither could anybody else). No way nohow. Not with that amount of features *and* stability.


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