linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Wedson Almeida Filho <wedsonaf@google.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Miguel Ojeda <ojeda@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	rust-for-linux <rust-for-linux@vger.kernel.org>,
	linux-kbuild <linux-kbuild@vger.kernel.org>,
	Linux Doc Mailing List <linux-doc@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 00/13] [RFC] Rust support
Date: Mon, 26 Apr 2021 16:26:10 +0200	[thread overview]
Message-ID: <CANiq72m_rzWEZ2Z1vWF79OtTvpuwaB1mAKihjY=VqRv+vtWQYA@mail.gmail.com> (raw)
In-Reply-To: <CACRpkdat-4BbKHMBerdxXBseMb9O3PiDRZmMLP_OWFE2ctSgEg@mail.gmail.com>

Hi Linus,

On Mon, Apr 26, 2021 at 2:18 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> I try to provide a good answer so I did sit down and look a bit more
> at rust and looked over your Binder example to at least reach the
> level of "a little knowledge of something is dangerous".

Thanks *a lot* for having spent some time to get to know the language a bit!

> For the record I kind of like the language.

That is great to hear :)

> A typical example is the way device drivers talk to actual hardware:
> readl()/writel(), readw()/writew(), readb()/writeb() for memory-mapped
> IO or inb()/outb() for port-mapped I/O.
>
> So there is for example this (drivers/gpio/gpio-pl061.c):
>
>         writeb(pl061->csave_regs.gpio_is, pl061->base + GPIOIS);
>         writeb(pl061->csave_regs.gpio_ibe, pl061->base + GPIOIBE);
>         writeb(pl061->csave_regs.gpio_iev, pl061->base + GPIOIEV);
>         writeb(pl061->csave_regs.gpio_ie, pl061->base + GPIOIE);
>
> We write a number of u32 into u32 sized registers, this
> pl061->base is a void __iomem * so a pretty unsafe thing to
> begin with and then we add an offset to get to the register
> we want.
>
> [...]
>
> How would I write these 4 registers in Rust? From the actual
> statements down to the CPU instructions, top to bottom,
> that is what a driver writer wants to know.

A function that writes to unconstrained addresses is indeed unsafe.
However, if one constraints them, then the functions might be able to
be made safe.

For instance, we could have a macro where you describe your hardware
registers and then code is generated that only allows to write to
those addresses. Not only that, but also make it properly typed, do
any needed masking/bit twiddling/unit conversion, etc.

This would be very similar to other code generation tools out there
used to simplify talking to hardware and maintain HDL mappings.

So instead of:

    writeb(x, pl061->base + GPIOIS);

you could say something like:

    pl061.write_gpio_is(x)

and the generated code should be the same (in fact, the Rust code
could forward the actual call to C to avoid rewriting any assembly --
but that can be done too if needed, e.g. if cross-language LTO does
not manage to inline as much as we want).

> If the result of the exercise is that a typical device driver
> will contain more unsafe code than not, then device drivers
> are not a good starting point for Rust in the Linux kernel.
> In that case I would recommend that Rust start at a point
> where there is a lot of abstract code that is prone to the
> kind of problems that Rust is trying to solve. My intuition
> would be such things as network protocols. But I may be
> wrong.

We may have some constructs that cannot be reasonably made safe, but
that is fine! As long as one needs to spell those out as `unsafe`, the
safe/unsafe split would be working as intended.

It is likely that some code will be written in "C style" nevertheless,
specially in the beginning. But, as explained above, we need to have a
mindset of writing safe abstractions wherever possible; and not just
try to mimic the kernel C side in everything.

It is also true that Rust brings some features that can be very useful
for non-HW-IO/"pure" code (state machines, ser/des, net protocols,
etc.) -- if someone wants to use Rust there, that is great, of course.

> I worry that it may become evident that introducing Rust
> in device drivers is *only* suggested because the number
> of affected platforms can be controlled (lacking some
> compiler arch targets?) rather than that being a place
> that needs memory safety. And then I think it is just a
> playground for Rust experiments and need to be proposed
> as such. But the idea was a real deployment I suppose.

We are proposing "leaf" modules not just because of the platforms
issue, but also because they introduce a smaller risk overall, i.e.
Rust support could be more easily dropped if the kernel community ends
up thinking it is not worth it.

If some platforms start seeing benefits from using Rust, it is our
hope that compiler vendors and companies behind arches will start
putting more resources on supporting Rust for their platforms too.

> It reminds me of Haskell monads for some reason.

Indeed! Result is pretty much Either.

> This is true for any constrained language. I suppose we could write
> kernel modules in Haskell as well, or Prolog, given the right wrappers,
> and that would also attain the same thing: you get the desired
> restrictions in the target language by way of this adapter.

You can indeed see Rust as a language that has brought some of the
"good ideas" to the systems programming domains.

However, while other languages can do all the fancy type things Rust
can do, the key is that it also introduces the necessary bits to
achieve manual (but safe) memory management for a lot of patterns;
while at the same time reading pretty much like C and C++ and without
removing some "down to the metal" features needed, such as raw
pointers, inline assembly, etc.

> The syntax and semantic meaning of things with lots of
> impl <T: ?Sized> Wrapper<T> for ... is just really intimidating
> but I suppose one can learn it. No big deal.

That syntax does take some time to get used to, indeed (like any other
generics or parameterized system).

Since one cannot introduce UB by mistake, it is "safe" to "play with
the language", which makes it way easier than e.g. some C++ features.
Plus the compiler is quite helpful.

> I have no idea how to perform this in
> Rust despite reading quite a lot of examples. We have
> created a lot of these helpers like FIELD_GET() and
> that make this kind of operations simple.

Bit twiddling and working with raw data can be done, e.g. take a look
into `u64::from_be_bytes()` or `core::mem::transmute()`. Things like
`offset_of`, `container_of`, intrinsics, inline assembly, etc. are
also possible.

In general, everything low-level you can do in C or C++, you can do in
Rust (and get the same kind of codegen).

When needed to simplify things, macros can be introduced too (we have
a few of those already, e.g. to declare a kernel module, to declare
file ops, etc.).

> 1. Expressiveness of language.
>
> If you look in include/linux/bitfield.h you can see how
> this is elaborately implemented to be "a bit" typesafe
> and if you follow the stuff around you will find that in
> some cases it will resolve into per-CPU assembly
> bitwise operations for efficiency. It's neat, it has this
> nice handicrafty feeling to it, we control the machine
> all the way down.

All that is fine in Rust (see above).

> But that took a few years to get here, and wherever
> we want to write a device driver in
> Rust this kind of stuff is (I suspect) something that is
> going to have to be reinvented, in Rust.

If you mean it in the sense that we need to have "similar" code in
Rust, yes, of course. But we can also forward things to the C side, so
some things do not need to be rewritten. The standard library also
provides quite a few utilities (more than C's), which also helps.

If you mean it in the sense that "Rust might be too high-level", not
really (as explained above etc.). Rust was designed with this usage in
mind; and is being used in embedded projects already.

> So this is where Rust maintainers will be needed. I will
> say something like "I need <linux/bitfield.h>
> in Rust" which I guess will eventually become a
> "use linux::bitfield" or something like that. Please
> fill in the blanks. In the beginning pushing tasks like
> that back on the driver writers will just encourage them
> to go and write the driver in C. So the maintainers need
> to pick it up.

We will try to help here as much as possible :)

This should also get fleshed out more when we have a couple drivers
that talk to hardware directly.

> 2. Duplication of core libraries.
>
> I worry about that this could quite soon result in two
> implementations of bitfield: one in C and one in Rust.
> Because the language will have its preferred idiomatic
> way of dealing with this, on the level above the
> per-arch assembly optimized bitwise instructions
> that need to be wrapped nicely for performance.
> Which means wrappers all the way down. (Oh well.)
>
> But double maintenance. Multiply with the number
> of such kernel abstractions we have. So it better not
> happen too much or pay off really well.

The Rust abstractions should reuse the C wherever possible. So it is
not a very big concern in that sense. But, yes, we need to have those
wrappers.

We expect that some modules will be easier to write than others,
specially at the beginning. So some subsystem may start to see some
drivers if the abstractions are already there or are easy enough to
make; while others may take longer.

> 3. Kickback in practical problem solving.
>
> Believe it or not device driver authors are not mainly
> interested in memory safety, overruns, dangling pointers,
> memory leaks etc. Maybe in a perfect world they
> would/should. But they are interested in getting hardware
> to work and want a toolbox that gives the shortest path
> from A to B. Telling them (or subsystem maintainers) all
> about how these things are solved elegantly by Rust is
> not a selling point.

Some of those (overruns, leaks, etc.) can turn into functional bugs
too (e.g. crashes), so even if some companies only care about "making
it work", they are still a good thing to eliminate (from their
perspective).

Even outside the memory-safety topic, Rust provides extra features to
make things reliable easier (like the strict typing and the error
handling guarantees with `Result` etc. we discussed above), so
companies should be up for it -- assuming the infrastructure is there
already.

But, of course, in the beginning, it will be harder for everyone
involved because we are not accustomed to either the language, the
utility functions ("headers" like `bitfield.h`), the way of writing
drivers in Rust, etc.

Cheers,
Miguel

  reply	other threads:[~2021-04-26 14:26 UTC|newest]

Thread overview: 203+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-14 18:45 [PATCH 00/13] [RFC] Rust support ojeda
2021-04-14 18:45 ` [PATCH 01/13] kallsyms: Support "big" kernel symbols (2-byte lengths) ojeda
2021-04-14 19:44   ` Matthew Wilcox
2021-04-14 19:59     ` Miguel Ojeda
2021-04-14 18:45 ` [PATCH 02/13] kallsyms: Increase maximum kernel symbol length to 512 ojeda
2021-04-14 23:48   ` Nick Desaulniers
2021-04-14 18:45 ` [PATCH 03/13] Makefile: Generate CLANG_FLAGS even in GCC builds ojeda
2021-04-14 18:59   ` Nathan Chancellor
2021-04-15 10:18     ` Miguel Ojeda
2021-04-14 23:46   ` Nick Desaulniers
2021-04-15  0:47     ` Miguel Ojeda
2021-04-14 18:45 ` [PATCH 04/13] Kbuild: Rust support ojeda
2021-04-14 23:19   ` Nick Desaulniers
2021-04-15  0:43     ` Miguel Ojeda
2021-04-15 18:03       ` Nick Desaulniers
2021-04-16 12:23         ` Miguel Ojeda
2021-04-17 19:35       ` Masahiro Yamada
2021-04-16 13:38   ` Peter Zijlstra
2021-04-16 17:05     ` Linus Torvalds
2021-04-16 17:47       ` Miguel Ojeda
2021-04-16 18:09         ` Al Viro
2021-04-16 18:57           ` Miguel Ojeda
2021-04-16 20:22             ` Willy Tarreau
2021-04-16 20:34               ` Connor Kuehl
2021-04-16 20:58                 ` Willy Tarreau
2021-04-16 21:39                   ` Miguel Ojeda
2021-04-16 22:04                     ` Willy Tarreau
2021-04-16 22:45                       ` Al Viro
2021-04-16 23:46                       ` Miguel Ojeda
2021-04-17  4:24                         ` Willy Tarreau
2021-04-17 15:38                           ` Miguel Ojeda
2021-04-16 21:19               ` Miguel Ojeda
2021-04-16 17:34     ` Miguel Ojeda
2021-04-19 19:58       ` David Sterba
2021-04-19 20:17         ` Matthew Wilcox
2021-04-19 21:03           ` Miguel Ojeda
2021-04-19 20:54         ` Miguel Ojeda
2021-04-14 18:45 ` [PATCH 05/13] Rust: Compiler builtins crate ojeda
2021-04-14 19:19   ` Linus Torvalds
2021-04-14 19:34     ` Miguel Ojeda
2021-04-14 18:45 ` [PATCH 06/13] Rust: Module crate ojeda
2021-04-14 18:45 ` [PATCH 08/13] Rust: Export generated symbols ojeda
2021-04-14 18:46 ` [PATCH 09/13] Samples: Rust examples ojeda
2021-04-14 19:34   ` Linus Torvalds
2021-04-14 19:42     ` Miguel Ojeda
2021-04-14 19:49       ` Matthew Wilcox
2021-04-16 11:46       ` Andrej Shadura
2021-04-14 23:24     ` Nick Desaulniers
2021-04-15  7:10       ` Greg Kroah-Hartman
2021-04-15  7:39         ` Nick Desaulniers
2021-04-15 12:42         ` Miguel Ojeda
2021-04-16 13:07         ` Sven Van Asbroeck
2021-04-16 13:20           ` Greg Kroah-Hartman
2021-04-14 18:46 ` [PATCH 10/13] Documentation: Rust general information ojeda
2021-04-14 22:17   ` Nick Desaulniers
2021-04-14 23:34     ` Miguel Ojeda
2021-04-14 18:46 ` [PATCH 11/13] MAINTAINERS: Rust ojeda
2021-04-14 21:55   ` Nick Desaulniers
2021-04-14 22:02     ` Miguel Ojeda
2021-04-14 22:36   ` Nick Desaulniers
2021-04-14 18:46 ` [PATCH 12/13] Rust: add abstractions for Binder (WIP) ojeda
     [not found] ` <20210414184604.23473-8-ojeda@kernel.org>
2021-04-14 19:31   ` [PATCH 07/13] Rust: Kernel crate Linus Torvalds
2021-04-14 19:50     ` Miguel Ojeda
2021-04-14 19:44 ` [PATCH 00/13] [RFC] Rust support Linus Torvalds
2021-04-14 20:20   ` Miguel Ojeda
2021-04-15  1:38     ` Kees Cook
2021-04-15  8:26       ` David Laight
2021-04-15 18:08         ` Kees Cook
2021-04-15 12:39       ` Miguel Ojeda
2021-04-14 20:09 ` Matthew Wilcox
2021-04-14 20:21   ` Linus Torvalds
2021-04-14 20:35     ` Josh Triplett
2021-04-14 22:08     ` David Laight
2021-04-14 20:29   ` Miguel Ojeda
2021-04-18 15:31   ` Wedson Almeida Filho
2021-04-15  0:22 ` Nick Desaulniers
2021-04-15 10:05   ` Miguel Ojeda
2021-04-15 18:58 ` Peter Zijlstra
2021-04-16  2:22   ` Wedson Almeida Filho
2021-04-16  4:25     ` Al Viro
2021-04-16  5:02       ` Wedson Almeida Filho
2021-04-16  5:39         ` Paul Zimmerman
2021-04-16  7:46         ` Peter Zijlstra
2021-04-16  7:09     ` Peter Zijlstra
2021-04-17  5:23       ` comex
2021-04-17 12:46       ` David Laight
2021-04-17 14:51       ` Paolo Bonzini
2021-04-19  7:32         ` Peter Zijlstra
2021-04-19  7:53           ` Paolo Bonzini
2021-04-19  8:26             ` Peter Zijlstra
2021-04-19  8:35               ` Peter Zijlstra
2021-04-19  9:02               ` Paolo Bonzini
2021-04-19  9:36                 ` Peter Zijlstra
2021-04-19  9:40                   ` Paolo Bonzini
2021-04-19 11:01                     ` Will Deacon
2021-04-19 17:14                   ` Linus Torvalds
2021-04-19 18:38                     ` Paolo Bonzini
2021-04-19 18:50                       ` Linus Torvalds
2021-04-22 10:03     ` Linus Walleij
2021-04-22 14:09       ` David Laight
2021-04-22 15:24       ` Wedson Almeida Filho
2021-04-26  0:18         ` Linus Walleij
2021-04-26 14:26           ` Miguel Ojeda [this message]
2021-04-26 14:40           ` Wedson Almeida Filho
2021-04-26 16:03             ` Miguel Ojeda
2021-04-27 10:54             ` Linus Walleij
2021-04-27 11:13               ` Robin Randhawa
2021-04-29  1:52               ` Wedson Almeida Filho
2021-04-26 18:01           ` Miguel Ojeda
2021-04-22 21:28       ` Miguel Ojeda
2021-04-26  0:31         ` Linus Walleij
2021-04-26 18:18           ` Miguel Ojeda
2021-04-27 11:13             ` Linus Walleij
2021-04-28  2:51               ` Kyle Strand
2021-04-28  3:10               ` Miguel Ojeda
2021-05-04 21:21                 ` Linus Walleij
2021-05-04 23:30                   ` Miguel Ojeda
2021-05-05 11:34                     ` Linus Walleij
2021-05-05 14:17                       ` Miguel Ojeda
2021-05-05 15:13                         ` Enrico Weigelt, metux IT consult
2021-05-06 12:47                         ` Linus Walleij
2021-05-07 18:23                           ` Miguel Ojeda
2021-04-16  4:27   ` Boqun Feng
2021-04-16  6:04     ` Nick Desaulniers
2021-04-16 18:47       ` Paul E. McKenney
2021-04-19 20:35         ` Nick Desaulniers
2021-04-19 21:37           ` Paul E. McKenney
2021-04-19 22:03           ` Miguel Ojeda
2021-04-16 20:48     ` Josh Triplett
2021-04-16  8:16   ` Michal Kubecek
2021-04-16  9:29     ` Willy Tarreau
2021-04-16 11:24 ` Peter Zijlstra
2021-04-16 13:07   ` Wedson Almeida Filho
2021-04-16 14:19     ` Peter Zijlstra
2021-04-16 15:04       ` Miguel Ojeda
2021-04-16 15:43         ` Peter Zijlstra
2021-04-16 16:21           ` Miguel Ojeda
2021-04-16 15:33       ` Wedson Almeida Filho
2021-04-16 16:14         ` Willy Tarreau
2021-04-16 17:10           ` Miguel Ojeda
2021-04-16 17:18             ` Peter Zijlstra
2021-04-16 18:08               ` Matthew Wilcox
2021-04-17 11:17                 ` Peter Zijlstra
2021-04-17 11:46                   ` Willy Tarreau
2021-04-17 14:24                     ` Peter Zijlstra
2021-04-17 14:36                       ` Willy Tarreau
2021-04-17 13:46                   ` David Laight
2021-04-16 17:37             ` Willy Tarreau
2021-04-16 17:46               ` Connor Kuehl
2021-04-20  0:24               ` Nick Desaulniers
2021-04-20  3:47                 ` Willy Tarreau
2021-04-20  5:56                 ` Greg Kroah-Hartman
2021-04-20  6:16                   ` Willy Tarreau
2021-04-29 15:38                     ` peter enderborg
2021-04-17 13:53           ` Wedson Almeida Filho
2021-04-17 14:21             ` Willy Tarreau
2021-04-17 15:23               ` Miguel Ojeda
2021-04-18 15:51               ` Wedson Almeida Filho
2021-04-17 12:41       ` David Laight
2021-04-17 13:01         ` Wedson Almeida Filho
2021-04-16 15:03     ` Matthew Wilcox
2021-04-17 13:29       ` Wedson Almeida Filho
2021-04-16 15:58     ` Theodore Ts'o
2021-04-16 16:21       ` Wedson Almeida Filho
2021-04-17 15:11       ` Paolo Bonzini
2021-04-16 14:21   ` Miguel Ojeda
2021-04-17 20:42 ` Richard Weinberger
2021-04-28 18:34 ` Mariusz Ceier
2021-04-28 20:25   ` Nick Desaulniers
2021-04-28 21:21   ` David Laight
2021-04-29 11:14     ` Kajetan Puchalski
2021-04-29 11:25   ` Kajetan Puchalski
2021-04-29 14:06     ` Mariusz Ceier
2021-04-29 14:13       ` Sven Van Asbroeck
2021-04-29 14:26         ` Willy Tarreau
2021-04-29 15:06       ` Al Viro
2021-04-29 16:09         ` Mariusz Ceier
2021-04-30  6:39     ` Thomas Schoebel-Theuer
2021-04-30  8:30       ` David Laight
2021-05-05 13:58       ` Enrico Weigelt, metux IT consult
2021-05-05 14:41         ` Miguel Ojeda
2022-06-20 15:11 ` Olliver Schinagl
2022-06-27 17:44   ` Miguel Ojeda
2022-07-18  6:56     ` Olliver Schinagl
2022-07-20 19:23       ` Miguel Ojeda
2022-07-20 20:21         ` Nicolas Pitre
2022-07-27  7:47           ` Olliver Schinagl
2022-07-27 13:32             ` Nicolas Pitre
2022-07-27  8:05         ` Olliver Schinagl
2022-07-28 10:21           ` Gary Guo
2022-07-28 12:09             ` Greg Kroah-Hartman
2022-07-28 12:28               ` Gary Guo
2022-07-28 20:45               ` Olliver Schinagl
2022-07-29  8:04                 ` Greg Kroah-Hartman
2022-07-28 20:43             ` Olliver Schinagl
2022-10-15 14:16               ` Olliver Schinagl
2022-10-16  1:44                 ` Bagas Sanjaya
2022-10-16  1:50                   ` Bagas Sanjaya
2022-10-16 13:23                 ` Josh Triplett
2021-04-29  5:20 Mariusz Ceier
2021-04-29  5:21 Mariusz Ceier
2021-04-29  8:18 ` David Laight
2021-07-30 23:22 Dillan Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANiq72m_rzWEZ2Z1vWF79OtTvpuwaB1mAKihjY=VqRv+vtWQYA@mail.gmail.com' \
    --to=miguel.ojeda.sandonis@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=wedsonaf@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).