← Back to context

Comment by baq

2 hours ago

Don’t spread FUD, you can check some example code yourself.

https://git.kernel.org/pub/scm/linux/kernel/git/a.hindborg/l...

Sorry but what have I said wrong? The nature of code written in kernel development is such that using unsafe is inevitable. Low-level code with memory juggling and patterns that you usually don't find in application code.

And yes, I have had a look into the examples - maybe one or two years there was a significant patch submitted to the kernel and number of unsafe sections made me realize at that moment that Rust, in terms of kernel development, might not be what it is advertised for.

> https://git.kernel.org/pub/scm/linux/kernel/git/a.hindborg/l..

Right? Thank you for the example. Let's first start by saying the obvious - this is not an upstream driver but a fork and it is also considered by its author to be a PoC at best. You can see this acknowledged by its very web page, https://rust-for-linux.com/nvme-driver, by saying "The driver is not currently suitable for general use.". So, I am not sure what point did you try to make by giving something that is not even a production quality code?

Now let's move to the analysis of the code. The whole code, without crates, counts only 1500 LoC (?). Quite small but ok. Let's see the unsafe sections:

rnvme.rs - 8x unsafe sections, 1x SyncUnsafeCell used for NvmeRequest::cmd (why?)

nvme_mq/nvme_prp.rs - 1x unsafe section

nvme_queue.rs - 6x unsafe not sections but complete traits

nvme_mq.rs - 5x unsafe sections, 2x SyncUnsafeCell used, one for IoQueueOperations::cmd second for AdminQueueOperations::cmd

In total, this is 23x unsafe sections/traits over 1500LoC, for a driver that is not even a production quality driver. I don't have time but I wonder how large this number would become if all crates this driver is using were pulled in into the analysis too.

Sorry, I am not buying that argument.

  • The idea behind the safe/unsafe split is to provide safe abstractions over code that has to be unsafe.

    The unsafe parts have to be written and verified manually very carefully, but once that's done, the compiler can ensure that all further uses of these abstractions are correct and won't cause UB.

    Everything in Rust becomes "unsafe" at some lower level (every string has unsafe in its implementation, the compiler itself uses unsafe code), but as long as the lower-level unsafe is correct, the higher-level code gets safety guarantees.

    This allows kernel maintainers to (carefully) create safe public APIs, which will be much safer to use by others.

    C doesn't have such explicit split, and its abstraction powers are weaker, so it doesn't let maintainer create APIs that can't cause UB even if misused.

  • > I am not sure what point did you try to make by giving something that is not even a production quality code?

    let's start by prefacing that 'production quality' C is 100% unsafe in Rust terms.

    > Sorry, I am not buying that argument.

    here's where we fundamentally disagree: you listed a couple dozen unsafe places in 1.5kLOC of code; let's be generous and say that's 10% - and you're trying to sell it as a bad thing, whereas I'm seeing the same numbers and think it's a great improvement over status quo ante.