Live data from Hacker News

A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

github.com

91–100 of 141 posts

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#91

Either I'm not understanding something that I thought I understood very well, or TFA's author's don't understand something that they think they understand very well. Their code is unsafe even on x86. You cannot write a single-writer, single-reader FIFO on modern processors without the use of memory barriers. Their attempt to use "volatile" instead of memory barriers is not appropriate. It could easily cause problems…

I think their point is you only need compiler barriers not actual barrier instructions on x86. volatile in practice has been the de facto way to get the effect of a compiler memory barrier for a long time even though it's not the best way to do it nowadays. The original purpose of it is literally preventing the compiler from getting rid of loads and stores and reordering them which is exactly what is needed when implementing a lockless FIFO. As long as all the stores and loads (including the actual FIFO payload) are volatile, it will work (volatile loads and stores are guaranteed to not be reordered with each other). After that the x86 guarantees about not reordering are very strong. Really the best argument against volatile for this kind of thing is actually the opposite of your point, volatile is too strong. It prevents more reordering than you actually want. Acquire/release semantics are less strong and give the compiler more flexibility.

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#92

Either I'm not understanding something that I thought I understood very well, or TFA's author's don't understand something that they think they understand very well. Their code is unsafe even on x86. You cannot write a single-writer, single-reader FIFO on modern processors without the use of memory barriers. Their attempt to use "volatile" instead of memory barriers is not appropriate. It could easily cause problems…

Another place it's meaningful to use `volatile` is in benchmarking and testing: to either ensure that a block of code is run despite not having any side effects, or to ensure that a block of code that should not be run is still compiled and emitted to binary.

But yes, `volatile` for what should be atomics is a clear code smell. I made quite a loud noise when I read "the code quality looks excellent" in the article.

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#93
post #67
post #57

Earlier quoted context omitted.

Unless you're the maintainer of the parking_lot crate, you're not "inventing your own". And since parking_lot is AFAIK the second most popular implementation of mutexes and RW locks in Rust (the most popular one being obviously the one in the Rust standard library, which wraps the OS-provided lock implementations), you can assume it's well tested.

Everything about which people tell you to “not invent your own” must be invented by someone .

In that case you should never run any software. Go live as a hunter-gatherer in the wilderness.

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#94

Great write-up! There may be a typo in section 3: > It will happily retire instruction 6 before instruction 5. If memory serves, although instructions can execute out-of-order, they retire in-order (hence the "re-order buffer").

Nice catch. I fixed it. I should have said "execute" rather than "retire".

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#95
post #21

Like quantum physics, memory ordering is deeply unintuitive (on platforms like ARM). Unlike quantum physics, which is an unfortunate immutable fact of the universe, we got ourselves into this mess and we have no one to blame but ourselves for it. I'm only somewhat joking. People need to understand these memory models if they intend on writing atomic operations in their software, even if they aren't currently targetin…

One piece of friction that hurts here is that the C++/Rust and ARM memory models aren't the same, and the consequences of this are unintuitive - compilers and CPUs can both screw with execution ordering. People who write in C++ should technically _only_ be concerned with the C++ memory model, but x86 has let them be very lax and undisciplined with std::memory_order_relaxed. ARM has some alluring constructs that don't…

[deleted]

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#96
post #71

Earlier quoted context omitted.

I doubt that. The number of ARM processors is far greater in reality than in x86 if we clarify it by saying “in operation” rather than historically and these stories will become more common but certainly won't see a “sharp increase”.

Of course. Any such flaws in the Linux kernel or any library used by Android should have been found by now, for example. But the number of ARM processors running developer/server/desktop stacks has been tiny until recently. In my experience, quite a lot of Linux on desktop software fails to even build on non x86_64 machines.

Are you kidding? Arm computers are by far the most common over the past 10 years. Computers are everywhere and servers and home computers account for at most 10% of the market for cpus and microcontrollers.

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#97
post #40

I spent some time trying to figure out why the lock-free read/write implementation is correct under x86, assuming a multiprocessor environment. My read of the situation was that there's already potential for a double-read / double-write between when the spinlock returns and when the head/tail index is updated. Turns out that I was missing something: there's only one producer thread, and only one consumer thread. If t…

Great points. I made some minor edits to address that and clarify some things. Thanks!

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#98
post #84

Earlier quoted context omitted.

I can’t imagine it’s an O2 vs O3 thing unless a compiler enables “fast-math” optimization to allow associativity. Neither clang nor GCC do this (neither does MSVC I think) - optimization levels never silently turn off IEEE754 floating point. I don’t know about ICC but it sounds like they stupidly enable fast math by default to try to win at benchmarks. Do you have anything to actually support this statement or did yo…

I did tests on Kahan summation recently on my macbook pro and -O3 defeated the algorithm while -O2 did not. Declaring the below variables as volatile restored error compensation with -O3. The relevant code is: kahan_y=g_sample_z - kahan_c; kahan_t=g_sample_z_sum + kahan_y; kahan_c=(kahan_t - g_sample_z_sum) - kahan_y; g_sample_z_sum=kahan_t; (this is in an inner loop where a new g_sample_z is calculated and then adde…

Sounds like a compiler bug to me. Can you file a bug to clang with a reduced standalone test (or I can do it for you if you share the standalone test).

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#99
post #56

Earlier quoted context omitted.

Memory ordering gets somewhat easier after you understand that flat memory shared by execution units is a leaky abstraction desperately patched over decades by layer and layers of hardware and software. Memory ordering is one way to represent message passing and synchronization between different cores and RAM. This why I think that "lock-free algorithms" is a misnomer, you still have synchronization, but you simply r…

Is there anything out there that exposes a better or tighter abstraction? Something not flat?

In practice you want memory reordering to be a thing because that's what allows you to reorder instructions that touch memory (both at compile time, and also at runtime by the processor), which is what enables a large part of the latency hiding that's going on.

Re: A bug that doesn’t exist on x86: Exploiting an ARM-only race condition

#100
post #56

Earlier quoted context omitted.

Is there anything out there that exposes a better or tighter abstraction? Something not flat?

A Dataflow architecture ISA would. It's been tried before. But, working out the entire software stack from scratch is a moonshot.

High-performance processors are data flow processors, which infer the data flow graph from the instruction stream using Tomasulo's algorithm.
Post reply on HN