Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider collecting proposals for 2024H2 Rust Project Goals #775

Open
jamesmunns opened this issue Jul 9, 2024 · 9 comments
Open

Consider collecting proposals for 2024H2 Rust Project Goals #775

jamesmunns opened this issue Jul 9, 2024 · 9 comments

Comments

@jamesmunns
Copy link
Member

RFC3614 introduced "Project Goals" which are intended to steer the focus and "big picture" of work in the project. The initial batch of goals, "2024H2", have already been selected.

Some external teams, like Rust for Linux, have articulated their desires for the project, and have been included on the "accepted" list.

As a WG, we could consider enumerating any goals we would like to propose to be added for the next selection process, "2025H1", which will begin discussions in October 2024, and will be selected in December 2024.

I'd like to recommend we consider whether there are any coherent goals we can propose to be part of the next project, to support any stumbling blocks in the embedded ecosystem, or to better position Rust as a preferrable choice for embedded development.

Originally posted by @jamesmunns in #773 (comment)

@BartMassey
Copy link
Member

I'd maybe possibly like to add a Project Goal around preserving the ability to use global mutable statics? I know this is controversial, but my personal opinion is that making them effectively unusable because of increasingly fancy memory models is not a great way forward for the Project, especially for the embedded folks. We'd have to work out the specifics of what we wanted, but things like breaking the ability to take a mutable reference to a global static in unsafe code seem especially vexing to me. Thoughts?

@jamesmunns
Copy link
Member Author

@BartMassey not sure if this is the right venue to discuss this either, but I can leave some quick notes, and happy to follow up in chat or somewhere else.

my personal opinion is that making them effectively unusable because of increasingly fancy memory models

To be clear, it's not like there is a fully specified memory model for items like this, and folks are proposing a new one that breaks things. The "current state" is that a lot of these details are entirely underspecified (for all of C, C++, and Rust!), and the fact that they happen to work is leaning on implementation details of different compilers and optimizers, that are allowed to break and change at any time!

I feel very strongly that:

  • There are correct ways to implement data structures that are clearly sound inside of Rust, today
  • We should do a better job of providing data structures that are usable and well documented. I'm working on doing this in grounded, which I'd like to promote to the WG, and perhaps upstream some of them to the std/core lib as well

We generally never should have been doing some of the things that we were doing with static mut, even with just "rust the language as written", not even considering things like strict provenance, the stacked borrows model, or the tree borrow model.

@ejpcmac
Copy link

ejpcmac commented Jul 9, 2024

At work (NXP), we’re currently evaluating Rust to program some of our firmwares. The platform I’m currently working on is based on a Cortex-M33 with a TrustZone-M, and I’ve come to discover that even the base for the TrustZone-M support (cmse_nonsecure_entry and abi_c_cmse_nonsecure_call) are still unstable features.

I’ve seen that the #[cmse_nonsecure_entry] could be transformed to an ABI, and that there are also other specialized ABIs that are available as unstable features. I think that stabilizing those would help a lot of folks in the embedded ecosystem.

@BartMassey
Copy link
Member

@jamesmunns Absolutely agree with your points.

The specific use case that finally set me off 🙃 was this: in one of the Discovery Book examples we have a couple of global static mut [u8; N] buffers that will only ever be accessed from one place in a protected context. Right now, we're doing unsafe { &mut buffer } to capture a reference to these. The resulting code is safe according to any memory model I can think of, but the compiler informs me that this code will be rejected in future Rust versions. I'm having a hard time thinking of a reasonable workaround, but I'm probably just missing something?

@jamesmunns
Copy link
Member Author

@BartMassey (this is my last response here, let's take the discussion elsewhere):

The primary driver for removing static mut is that it's very easy to misuse, and there are other unsafe building blocks (UnsafeCell) available. Your specific case might be reasonable! But that's not the only way static mut can be used, so using UnsafeCell (or something like grounded::GroundedCell) might be preferable.

@eldruin
Copy link
Member

eldruin commented Jul 26, 2024

Maybe #774 is worth considering here.

@diondokter
Copy link

At work (NXP), we’re currently evaluating Rust to program some of our firmwares. The platform I’m currently working on is based on a Cortex-M33 with a TrustZone-M, and I’ve come to discover that even the base for the TrustZone-M support (cmse_nonsecure_entry and abi_c_cmse_nonsecure_call) are still unstable features.

I’ve seen that the #[cmse_nonsecure_entry] could be transformed to an ABI, and that there are also other specialized ABIs that are available as unstable features. I think that stabilizing those would help a lot of folks in the embedded ecosystem.

To note here, two of my colleagues have been making PRs for this. I wanted to write that they're still open, but apparently they've just been merged!
rust-lang/rust#127766

Tracking issues: (Seems like there's not much left)
rust-lang/rust#81391
rust-lang/rust#75835

@BartMassey
Copy link
Member

I'd like to amend my previous proposal around mutable statics to be way more general as a Project Goal: "Stabilize and clearly document Rust memory semantics." This is important for everybody, not just embedded, but it really matters a lot to us. Mara's book is a fantastic start, but I feel like we don't even have a fully-specified model yet, or if we do I don't think I understand it at this point, and I'm not sure a huge number of other people do either. Recent discussions I've been part of are I think not promising in this regard, but maybe it's just me.

I'm kind of surprised this isn't already a Project Goal. I'm not sure we can own it, since there's folks on the compiler team who are doing most of the work, but we could at least raise it as an "orphaned" goal.

Thoughts?

@jannic
Copy link
Member

jannic commented Oct 1, 2024

I'm not sure we can own it, since there's folks on the compiler team who are doing most of the work, but we could at least raise it as an "orphaned" goal.

Perhaps we could define a more specific goal, focused on requirements of embedded rust. Something like "Soundness requirements for embedded targets should be documented."

There are a lot of questions that (to my knowledge) are not really answered by any official rust documentation:

  • What initialization needs to be performed before jumping to the rust entry point?
    • Are there conditions under which rust code can be executed before that point, safely?
  • Are there any operations that should be considered unsafe on an embedded target?
    • Eg. disabling clock or even power for some memory range surely can have severe consequences. But is it possible to specify a clear and useful rule when a function should be marked unsafe?
    • This is likely more an API guideline than a strict rule
  • What is considered a race condition if memory is accessed by hardware?
    • DMA
    • Registers that are changing their value without a write access by Rust code (timers etc?)
    • Changing memory mappings
  • How can inherently racy registers be accessed?
    • write_volatile docs say "In particular, a race between a write_volatile and any other operation (reading or writing) on the same location is undefined behavior."
    • for example the RP2040 spinlock registers are meant to be accessed concurrently
    • can and should the write_volatile docs extended by something like "…unless hardware provides a defined behavior of concurrent accesses"?
  • Is there a sound way to access RAM (and other memory regions) outside the control of the Rust abstract machine?
    • It's probably just fine, and can be accessed using normal pointer read/writes, but is it documented somewhere?
    • Can such pointers be converted to references, essentially bringing the memory into control of the abstract machine?
  • Define terms like 'threads' for targets without an OS. (Relation to multi-core MCUs, interrupts)
  • …to be continued…

Even if we can't answer all of these questions without the compiler team, we could at least make suggestions, stating what we'd like the answers to be and what the consequences for embedded rust would be if the answers were different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants