From: Miguel Ojeda <firstname.lastname@example.org> To: Linus Walleij <email@example.com> Cc: Wedson Almeida Filho <firstname.lastname@example.org>, Peter Zijlstra <email@example.com>, Miguel Ojeda <firstname.lastname@example.org>, Linus Torvalds <email@example.com>, Greg Kroah-Hartman <firstname.lastname@example.org>, rust-for-linux <email@example.com>, linux-kbuild <firstname.lastname@example.org>, Linux Doc Mailing List <email@example.com>, linux-kernel <firstname.lastname@example.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 <email@example.com> 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
next prev parent reply other threads:[~2021-04-26 14:26 UTC|newest] Thread overview: 201+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-04-14 18:45 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 07/13] Rust: Kernel crate ojeda 2021-04-14 19:31 ` Linus Torvalds 2021-04-14 19:50 ` Miguel 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 2021-04-14 18:46 ` [PATCH 13/13] Android: Binder IPC in Rust (WIP) 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 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' \ --firstname.lastname@example.org \ --email@example.com \ --firstname.lastname@example.org \ --email@example.com \ --firstname.lastname@example.org \ --email@example.com \ --firstname.lastname@example.org \ --email@example.com \ --firstname.lastname@example.org \ --email@example.com \ --firstname.lastname@example.org \ --subject='Re: [PATCH 00/13] [RFC] Rust support' \ /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
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).