On Mon, Oct 29, 2018 at 10:23:07AM +0100, Arnd Bergmann wrote: > On Mon, Oct 29, 2018 at 2:21 AM Paul E. McKenney <paul...@linux.ibm.com> > wrote: > > > > On Mon, Oct 29, 2018 at 12:10:03AM +0100, Andrea Parri wrote: > > > Hopefully, with Paul's proper email address this time, > > > > > > Andrea > > > > > > On Mon, Oct 29, 2018 at 12:06:27AM +0100, Andrea Parri wrote: > > > > Hi, > > > > > > > > memory-barriers.txt says: > > > > > > > > [on "store tearing"] > > > > > > > > "In fact, a recent bug (since fixed) caused GCC to incorrectly use > > > > this optimization in a volatile store.". > > > > > > > > I was wondering if you could help me retrieve some reference/discussions > > > > about this? > > > > This was quite some time ago, but it involved a 32-bit volatile store > > of a constant such as 0x10001. The machine in question had a narrow > > store-immediate instruction, so the compiler emitted a pair of 16-bit > > store-immediate instructions. This bug was fixed, though only after > > significant screaming and shouting. > > A related issue I remember was on ARMv5 (an architecture without > unaligned access) where a function like )not sure if this specific > one triggers it, but something like it did) > > struct my_registers { > u32 a; > u32 b; > u32 c; > } __attribute__((packed)); > #define __raw_writel(p, v) do { (volatile u32 __iomem *)(p) = (v); } while (0) > void my_write_a(struct my_registers __iomem *r, u32 val) > { > __raw_writel(&r->a, val); > } > > The above is undefined behavior because we cast from an unaligned > data type to a 32-bit aligned type, and gcc resolved this by turning the > intended 32-bit store into a set of 8 bit stores. We worked around this > by changing __raw_writel() into a inline assembly that always uses a > 32-bit store.
I had either missed or forgotten this one, nice example of store tearing! Thanx, Paul