ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
starblue1 has quit [Ping timeout: 268 seconds]
starblue1 has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
dungus has joined #rust-embedded
causal has quit [Quit: WeeChat 3.5]
dungus has quit [Quit: leaving]
inara has quit [Quit: Leaving]
inara has joined #rust-embedded
<re_irc> <jannic> Isn't this plain wrong? Iirc atomic load and store are available, just not CAS, and that's exactly what the old target file described.
<re_irc> <jannic> Or is this not guaranteed for all thumbv6m chips? I didn't check the ARM specs.
crabbedhaloablut has quit [Write error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
Foxyloxy has joined #rust-embedded
<re_irc> <adamgreig> Hmm, I guess this changes because of the upstream llvm change in https://reviews.llvm.org/D120026
<re_irc> <jannic> I don't fully understand the reasoning behind the change in rustc: is it forced by the change in LLVM, or is there a choice to revert it in rustc?
<re_irc> <adamgreig> My (currently very rough) understanding is that rustc has to change something due to the llvm change, but potentially it could handle this in a different way for thumbv6 targets that doesn't just horribly break a ton of existing code
<re_irc> <adamgreig> The suggestion to use volatile instead of atomic is kind of annoying because in rust volatile is a property of the access but atomics are their own type... there's no VolatileU32
<re_irc> <jannic> Is there a nightly which includes the LLVM change and not the rustc one? Does that generate broken code?
<re_irc> (I only have mobile date ATM and can't download the nightly versions)
<re_irc> <jannic> * data
<re_irc> <adamgreig> I guess we'd have noticed by now if a nightly had broken cm0, so probably the latest llvm isn't merged into nightly?
<re_irc> <jannic> Well it may generate technically broken code which happens to work because in practice none of the cortex-m multi core chips use data caches.
<re_irc> <adamgreig> They certainly do have and use dcaches
<re_irc> <adamgreig> Oh, not cortex-m0
<re_irc> <jannic> m0, that's is.
<re_irc> <adamgreig> ARMv6-M can't have a dcache architecturally, it's not in the arch reference manual, so it would be outside the scope of atomics anyway
<re_irc> <adamgreig> But even on cm7 atomic ops don't Interact with the dcache
<re_irc> <jannic> The ARM talks about visibility and ordering of memory access though, doesn't it? How does that make sense without caches?
<re_irc> <adamgreig> I think that's mostly to do with the effect of fences and potential cpu reordering of accesses, rather than anything strictly to do with a cache
<re_irc> <adamgreig> this is maybe wrong and I mean "cortex-m0" not "ARMv6-M"
<re_irc> <adamgreig> armv6-m does talk about how any potential system caches would interact with the different memory region attributes, though the same rules about exclusives apply as for cm7 in that link above
<re_irc> <adamgreig> A3.5.2 in the v6-m arch reference manual
<re_irc> <jannic> To be honest I don't even know which cores map to armv6-m.
<re_irc> <adamgreig> cm0, cm0+, cm1
<re_irc> <jannic> I'm at a music festival today so I have very limited resources :-)
<re_irc> <adamgreig> i don't think the presence of caches has any effect on whether llvm is generating correct atomic code, basically
<re_irc> <adamgreig> my still very rough understanding is that llvm may want to always handle all atomic ops (regular load/store and CAS) the same way, and the problem is if you allow atomic load/store to directly do a fence and load/store, it no longer plays well with putting the CAS operations through the software shims of __atomic_* because they won't care about any potential software lock those use
<re_irc> <adamgreig> * "__atomic_*"
<re_irc> <adamgreig> on rust this isn't obviously an issue because the CAS operations are simply not exposed at all
<re_irc> <adamgreig> hmm yea, more discussion here: https://github.com/rust-lang/rust/pull/98333
<re_irc> <James Munns> Amanieu opened https://github.com/rust-lang/rust/issues/99668 to track this regression
<Amanieu> I'm going to revert that change for now. It's only needed for LLVM 15 which is still far away.
<re_irc> <James Munns> And a revert commit for the PR thejpster linked: https://github.com/rust-lang/rust/pull/99670
<re_irc> <adamgreig> does the atomic-polyfill CAS emulation on armv6 prevent a non-emulated load/store from interfering with an emulated CAS?
<re_irc> <mabez> Selfishly, I'm quite glad LLVM reverted the arm change, because it means there is hope for getting atomic load/stores for riscvi targets 😅
<re_irc> <mabez> Obviously I don't want the change to break half the embedded rust ecosystem though...
<re_irc> <adamgreig> LLVM reverted the arm change?
<re_irc> <mabez> Reverted allowing emitting atomic codegen for thumbv6 targets
<re_irc> <adamgreig> as in, now only emits "__atomic_*" lib calls even for load/store?
<re_irc> <mabez> Yes :)
<re_irc> <adamgreig> I can certainly see how it fixes a bug in LLVM
<re_irc> <adamgreig> how does it affect riscv for you?
<re_irc> <adamgreig> (I'm still not sure I follow, did they revert the change that causes it to only emit __atomic, or are you saying you're glad they've fixed this very longstanding bug and now only emit __atomic?)
<re_irc> <mabez> Well indirectly it affects riscv. LLVM refused patches to allow atomic codegen for riscv non atomic targets and then upstream rust wouldn't allow PR's adding manual lowering for riscv targets.
<re_irc> I'm glad the arm codegen has been removed in LLVM 15 because it forces upstream rust to handle this properly instead if relying on an LLVM bug
<re_irc> <mabez> And in fixing it properly should allow other targets, like riscv to get atomic load/stores
<re_irc> <mabez> But obviously the way to do this is to discuss it instead of just breaking half the embedded Rust ecosystem, which fortunately Amanieu is on top of
<re_irc> <adamgreig> ah yea, got it, I agree
<re_irc> <adamgreig> everything that touches llvm's memory model like this seems to end up kind of cursed, perhaps because it's hard to definitively say how something is even meant to behave
<re_irc> <adamgreig> but at least if rust does provide its own lowering of Atomic* load/store for thumbv6 there seems to be no reason it couldn't also do this for rv non-A, and both cases would be clearly documented why this is OK and why it's different from LLVM
<re_irc> <mabez> adamgreig: Exactly, that's what I'm hoping for at least!
causal has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
Amadiro has joined #rust-embedded
Amadiro_ has joined #rust-embedded
Amadiro has quit [Ping timeout: 255 seconds]
<cr1901> https://github.com/rust-lang/rust/issues/99668 Amanieu: I believe this also applies to msp430, but I'm gonna be honest... the whole "msp430 and LLVM atomics" thing is a mess 1/2
<cr1901> While I can explain what atomic operations msp430 offers in terms of "msp430 has bitset/clear insns that will not be interrupted before completing", and "msp430 is a single core arch", I don't know how to map that back to what LLVM and Rust expects
<cr1901> Historically, I've used a separate crate for implementing e.g. AtomicBool that uses inline assembly
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
<re_irc> <thalesfragoso> jannic: CM7 has something called store queue, that is essentially a cache, but it isn't something else than the normal optional dcache
<re_irc> <thalesfragoso> * is
<re_irc> <thalesfragoso> Basically, stores in normal memory can be re-ordered in the store queue, that's where DMB (fences) from atomics come into play
<re_irc> <thalesfragoso> cr1901: The problem is that LLVM considers "software atomics" as "first class", so your normal hardware implementation would break them
<re_irc> <thalesfragoso> Even if you use inline asm
<re_irc> <thalesfragoso> I.e. they expose "software CAS" which would break with any other atomic implementation, even just normal load/store
<re_irc> <thalesfragoso> But rust doesn't expose software atomics, so there's hope, but that needs to be done in rustc itself
<re_irc> <thalesfragoso> That is usually only needed when dealing with multi master situations, e.g. multi core or DMA
<re_irc> <thalesfragoso> And that's the cause of a year-long bug in ST's official Ethernet driver
<re_irc> <thalesfragoso> * years-long
<cr1901> thalesfragoso: >The problem is that LLVM considers "software atomics" as "first class", so your normal hardware implementation would break them <-- I'm afraid I don't understand this line at all.
<cr1901> What is the problem? What normal hardware implementation? Break what?
<cr1901> >they expose "software CAS"... what is "they" referring to? My crate or "the code LLVM generates"?
<re_irc> <thalesfragoso> cr1901: libatomic exposes software implementations for atomics, they are used for CAS operations where the target doesn't support CAS, e.g. tumbv6. If you link code that uses normal store/load for atomics then you break libatomic
<re_irc> <thalesfragoso> Rust doesn't link to libatomic and doesn't plan to, but LLVM wants to support such software implementations, that's why they did what they did
<cr1901> What does libatomic disable interrupts for thumbv6?
<re_irc> <thalesfragoso> Tbh, I have no idea what libatomic does exactly on specific targets
<re_irc> <thalesfragoso> But it's known that you can't mix its atomics with others
<cr1901> msp430 atomic lowering isn't implemented in LLVM. If LLVM sees those insns, the backend bails
<cr1901> So I use a separate Rust crate as a workaround. This seems to work fine, especially since the LLVM backend itself bails before it would ever try to use libatomic
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
<re_irc> <thejpster> thalesfragoso: I guess the usual answer is that it asks the OS for help.
<re_irc> <thejpster> I remember my early embedded projects where I just used gcc targeting arm-none-linux-gnueabi. It was not great 😂
<re_irc> <dirbaio> which uses ... spinlocks implemented with atomics. How's that not a chicken-and-egg? 😂
<cr1901> The smallest atomic primitives must be impl'd in terms of "something that either fails or succeeds without there being a visible halfway point". These could be smaller atomics, OS support, or disabling/enabling interrupts.
<cr1901> s/smallest//
<cr1901> The latter two only work on single core, which AFAIK makes multicore w/o some sort of small atomic primitive not very useful in practice.
<re_irc> <dirbaio> yeah but.. this _is_ the thing that implements atomics for archs without hardware CAS, based on global spinlocks
<re_irc> <dirbaio> but these spinlocks use CAS 😂
<cr1901> Where's the CAS?
<cr1901> (in the spinlocks?)
<cr1901> (Anyways if it's what you say- CAS in terms in CAS- I have no idea how that can work either :P...)
<re_irc> <dirbaio> anyway rust bins don't link llvm's "compiler-rt", only rust's "compiler-builtins"
<re_irc> <dirbaio> which doesn't define these libcalls
* cr1901 is operating at like 5% of capacity today :(
<re_irc> <dirbaio> so using atomics would always be a linker error for these targets, if rust didn't disable "std::sync::atomic"
<cr1901> Because LLVM lowering from std::sync::atomic would automatically generate to libatomic calls?
<re_irc> <dirbaio> yep
<cr1901> How does Rust know to generate the proper LLVM? AtomicBool and friends don't seem special (no special attributes)
<cr1901> wait
<cr1901> atomic_load/atomic_store*
<cr1901> Which in turn eventually calls "https://doc.rust-lang.org/src/core/intrinsics.rs.html#210", which has extern "rust-instrinsic"
<cr1901> which sounds special enough that I don't care after that point :P
<re_irc> <dirbaio> yeah, rustc lowers that to llvm ir atomic ops, then llvm lowers it to either the right asm instructions or libcalls depending on the target
crabbedhaloablut has quit [Ping timeout: 268 seconds]
loki_val has joined #rust-embedded
loki_val has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
emerent has quit [Ping timeout: 240 seconds]
emerent has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
causal has quit [Quit: WeeChat 3.5]