On Sun, 9 Feb 2025 at 11:10, David Laight <david.laight.linux@xxxxxxxxx> wrote: > > +#define barrier_nospec() __rmb() This is one of those "it happens to work, but it's wrong" things. Just make it explicit that it's "lfence" in the current implementation. Is __rmb() also an lfence? Yes. And that's actually very confusing too too. Because on x86, a regular read barrier is a no-op, and the "main" rmb definition is actually this: #define __dma_rmb() barrier() #define __smp_rmb() dma_rmb() so that it's only a compiler barrier. And yes, __rmb() exists as the architecture-specific helper for "I need to synchronize with unordered IO accesses" and is purely about driver IO. We should have called it "relaxed_rmb()" or "io_rmb()" or something like that, but the IO memory ordering issues actually came up before the modern SMP ordering issues, so due to that historical thing, "rmb()" ends up being about the IO ordering. It's confusing, I know. And historical. And too painful to change because it all works and lots of people know the rules (except looking around, it seems possibly the sunrpc code is confused, and uses "rmb()" for SMP synchronization) But basically a barrier_nospec() is not a IO read barrier, and an IO read barrier is not a barrier_nospec(). They just happen to be implemented using the same instruction because an existing instruction - that nobody uses in normal situations - ended up effectively doing what that nospec barrier needed to do. And some day in the future, maybe even that implementation equivalence ends up going away again, and we end up with new barrier instructions that depend on new CPU capabilities (or fake software capabilities: kernel bootup flags that say "don't bother with the nospec barriers")., So please keep the __rmb() and the barrier_nospec() separate, don't tie them together. They just have *soo* many differences, both conceptual and practical. Linus