From d8b56c8eabcc2c90df56390fad1531f0aae236ac Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 24 Jul 2015 19:43:18 +0000 Subject: [PATCH] Add a comment discussing the appropriate use of the atomic_*() functions with acquire and release semantics versus the *mb() functions on amd64 processors. Reviewed by: bde (an earlier version), kib Sponsored by: EMC / Isilon Storage Division --- sys/amd64/include/atomic.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 7892d51ec19..016aa70e04b 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -32,6 +32,25 @@ #error this file needs sys/cdefs.h as a prerequisite #endif +/* + * To express interprocessor (as opposed to processor and device) memory + * ordering constraints, use the atomic_*() functions with acquire and release + * semantics rather than the *mb() functions. An architecture's memory + * ordering (or memory consistency) model governs the order in which a + * program's accesses to different locations may be performed by an + * implementation of that architecture. In general, for memory regions + * defined as writeback cacheable, the memory ordering implemented by amd64 + * processors preserves the program ordering of a load followed by a load, a + * load followed by a store, and a store followed by a store. Only a store + * followed by a load to a different memory location may be reordered. + * Therefore, except for special cases, like non-temporal memory accesses or + * memory regions defined as write combining, the memory ordering effects + * provided by the sfence instruction in the wmb() function and the lfence + * instruction in the rmb() function are redundant. In contrast, the + * atomic_*() functions with acquire and release semantics do not perform + * redundant instructions for ordinary cases of interprocessor memory + * ordering on any architecture. + */ #define mb() __asm __volatile("mfence;" : : : "memory") #define wmb() __asm __volatile("sfence;" : : : "memory") #define rmb() __asm __volatile("lfence;" : : : "memory")