The following two citations seem contradicting:
https://www.kernel.org/doc/Documentation/atomic_ops.txt
int atomic_cmpxchg(atomic_t *v, int old, int new);
This performs an atomic compare exchange operation on the atomic value v, with the given old and new values. Like all atomic_xxx operations, atomic_cmpxchg will only satisfy its atomicity semantics as long as all other accesses of *v are performed through atomic_xxx operations.
atomic_cmpxchg requires explicit memory barriers around the operation.
vs
https://www.kernel.org/doc/Documentation/memory-barriers.txt
Any atomic operation that modifies some state in memory and returns information about the state (old or new) implies an SMP-conditional general memory barrier (smp_mb()) on each side of the actual operation (with the exception of explicit lock operations, described later). These include:
<...> atomic_xchg(); atomic_cmpxchg(); <...>
These are used for such things as implementing LOCK-class and UNLOCK-class operations and adjusting reference counters towards object destruction, and as such the implicit memory barrier effects are necessary.
So should one put memory barriers around atomic_xchg()
manually?
I'm not aware yet about Linux kernel programming specifics, so here is a partial (general) answer.
On x86, this operation carries full memory fence with it, there is no need in
mfence
/lfence
/sfence
aroundcmpxchg
op.On other architectures with relaxed memory model, it can be coupled with other memory semantics, e.g. "release", depending on how
atomic_cmpxchg()
is translated to the op codes.It's on the processor side of things. However, there is compiler which can also reorder the operations, so if compiler barrier is not implied by
atomic_cmpxchg()
(by e.g.__asm__ __volatile__
), you would need one.