On Thu, Mar 10, 2022 at 10:45:47AM +0000, Laurence Tratt wrote: > On Thu, Mar 10, 2022 at 09:05:54AM +0000, Visa Hankala wrote: > > Hello Visa, > > > In general, atomic_* functions have not provided implicit memory > > barriers on OpenBSD. > > I've used atomics fairly extensively in other settings. Forgive me if I'm > explaining the obvious, but I had a devil of a job making sense of this > stuff a few years back, and so perhaps others might find it useful to expand > on this point. > > Quick background: modern CPUs come in two main flavours, weakly ordered > (e.g. most Arm systems) and strongly ordered (e.g. x86), which determine the > rules of when multiple cores can see the reads/writes of other cores. Weakly > ordered systems can move/optimise loads/stores around more than strongly > ordered systems (so code that seems to work fine on x86 can then fail on > Arm). > > There are in a sense two "safe" ways to use atomics: to assume that each > atomic is isolated and that reading/writing to it tells you nothing about any > other location in memory; or that every atomic is fully ordered with respect > to every other atomic (i.e. no reorderings of atomic operations are allowed). > The former is fast but (without additional operations) can't even express > a mutex safely. The latter doesn't have very good performance. > > C11 thus allows you to do various atomic operations with different memory > orderings [1] so that you can choose on a case-by-case basis what you're > prepared to tolerate. "relaxed" is the most efficient but has the least > guarantees; "seq_cst" is the least efficient but has the most guarantees. > > I would be very nervous about adding further atomic functions (as in the > original diff) to OpenBSD that don't allow the user to specify what ordering > they want: it's impossible to pick a memory ordering that suits all use > cases. For example, neither READ_ONCE nor the existing atomic_* instructions > define an ordering: I suppose I'd have to to assume they're relaxed. I worry > that people might assume these atomic operations provide greater guarantees > than they actually do.
the existing atomic_foo ops provided in the kernel are implicitly relaxed. as you say, that make no claims about ordering. if you want ordering then you use explicit calls membar_foo ops. > Fortunately since, AFAICT, we already use C11 (or C17?!) for base, and LLVM > includes all of the relevant functions (e.g. the compare_exchange family > [2]) I don't think we need to add any functions of our own? It might not > even be a bad idea to deprecate the current atomic_* functions in base > and migrate to the C11 alternatives? not all our archs are on llvm/clang or even a recent gcc, and there are (what i will generously call) gaps in the set of atomic ops different cpus actually implement themselves. having the atomic_foo and membar_foo apis in the kernels distinct from the c/compiler provided ones makes it a bit more obvious that the rules are different and some care should be taken. cheers, dlg > > > Laurie > > [1] https://en.cppreference.com/w/c/atomic/memory_order > [2] https://en.cppreference.com/w/c/atomic/atomic_compare_exchange >
