locking/arch: Add WRITE_ONCE() to set_mb()
authorPeter Zijlstra <peterz@infradead.org>
Tue, 12 May 2015 08:52:27 +0000 (10:52 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 19 May 2015 06:31:59 +0000 (08:31 +0200)
Since we assume set_mb() to result in a single store followed by a
full memory barrier, employ WRITE_ONCE().

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
12 files changed:
arch/arm/include/asm/barrier.h
arch/arm64/include/asm/barrier.h
arch/ia64/include/asm/barrier.h
arch/metag/include/asm/barrier.h
arch/mips/include/asm/barrier.h
arch/powerpc/include/asm/barrier.h
arch/s390/include/asm/barrier.h
arch/sparc/include/asm/barrier_64.h
arch/x86/include/asm/barrier.h
arch/x86/um/asm/barrier.h
include/asm-generic/barrier.h
include/linux/compiler.h

index d2f81e6b8c1cc5adb914ce38a7ab991b25801137..993150aea681e082519026ee4054be9b11655b4b 100644 (file)
@@ -81,7 +81,7 @@ do {                                                                  \
 #define read_barrier_depends()         do { } while(0)
 #define smp_read_barrier_depends()     do { } while(0)
 
-#define set_mb(var, value)     do { var = value; smp_mb(); } while (0)
+#define set_mb(var, value)     do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 #define smp_mb__before_atomic()        smp_mb()
 #define smp_mb__after_atomic() smp_mb()
index 71f19c4dc0dee8c8a74bbdea252f73432e0b1aa5..ff7de78d01b8fe1595a937b5f7a12afbe190ab66 100644 (file)
@@ -114,7 +114,7 @@ do {                                                                        \
 #define read_barrier_depends()         do { } while(0)
 #define smp_read_barrier_depends()     do { } while(0)
 
-#define set_mb(var, value)     do { var = value; smp_mb(); } while (0)
+#define set_mb(var, value)     do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 #define nop()          asm volatile("nop");
 
 #define smp_mb__before_atomic()        smp_mb()
index f6769eb2bbf9b5ff8774017ac0eb332fcc7309d9..03117e7b2ab8dd7e007f7e2b49e47b0387bcb450 100644 (file)
@@ -82,7 +82,7 @@ do {                                                                  \
  * acquire vs release semantics but we can't discuss this stuff with
  * Linus just yet.  Grrr...
  */
-#define set_mb(var, value)     do { (var) = (value); mb(); } while (0)
+#define set_mb(var, value)     do { WRITE_ONCE(var, value); mb(); } while (0)
 
 /*
  * The group barrier in front of the rsm & ssm are necessary to ensure
index d703d8e26a656c1560202d3c1af6a39ed95771e5..97eb018a2933b7660e87d8c99ae7fbd84e5b7071 100644 (file)
@@ -84,7 +84,7 @@ static inline void fence(void)
 #define read_barrier_depends()         do { } while (0)
 #define smp_read_barrier_depends()     do { } while (0)
 
-#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
+#define set_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 #define smp_store_release(p, v)                                                \
 do {                                                                   \
index 2b8bbbcb9be0e9f8c5c6f7dbc1a2c6f692185443..cff1bbdaa74aee67b7926c70160f8116d41c2c24 100644 (file)
 #endif
 
 #define set_mb(var, value) \
-       do { var = value; smp_mb(); } while (0)
+       do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 #define smp_llsc_mb()  __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
 
index a3bf5be111ff1d073eb329476ce773c07ce32ed5..2a072e48780d2af914c27963d57c1cd6f1271c8e 100644 (file)
@@ -34,7 +34,7 @@
 #define rmb()  __asm__ __volatile__ ("sync" : : : "memory")
 #define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
 
-#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define set_mb(var, value)     do { WRITE_ONCE(var, value); mb(); } while (0)
 
 #ifdef __SUBARCH_HAS_LWSYNC
 #    define SMPWMB      LWSYNC
index 8d724718ec21c8d0331e1b8fbc14c96cb5892649..b66cd53d35fc0808120c12732b7c198c3bea0153 100644 (file)
@@ -36,7 +36,7 @@
 #define smp_mb__before_atomic()                smp_mb()
 #define smp_mb__after_atomic()         smp_mb()
 
-#define set_mb(var, value)             do { var = value; mb(); } while (0)
+#define set_mb(var, value)             do { WRITE_ONCE(var, value); mb(); } while (0)
 
 #define smp_store_release(p, v)                                                \
 do {                                                                   \
index 76648941fea71b4327e058d6e995a3331587541c..125fec7512f4bd84c693c702ca5a9a825f544827 100644 (file)
@@ -41,7 +41,7 @@ do {  __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
 #define dma_wmb()      wmb()
 
 #define set_mb(__var, __value) \
-       do { __var = __value; membar_safe("#StoreLoad"); } while(0)
+       do { WRITE_ONCE(__var, __value); membar_safe("#StoreLoad"); } while(0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
index 959e45b81fe29192b0f1c97a65e028e7314f603d..9de5cde133a1e78820d23425fdc159ce18fb5760 100644 (file)
@@ -40,7 +40,7 @@
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
-#define set_mb(var, value) do { var = value; barrier(); } while (0)
+#define set_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
 #endif /* SMP */
 
 #define read_barrier_depends()         do { } while (0)
index 7e8a1a6504356159bd1b604b53de4ed194ddd19c..cc0cb01f346d6cf391fe32ed990a713bea071a38 100644 (file)
@@ -39,7 +39,7 @@
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
-#define set_mb(var, value) do { var = value; barrier(); } while (0)
+#define set_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
 
 #define read_barrier_depends()         do { } while (0)
 #define smp_read_barrier_depends()     do { } while (0)
index f5c40b0fadc2a50be563304727db2e7ad7fe6699..3938716b44d74ff8ddf0d25739af2ea1c3f7162a 100644 (file)
@@ -67,7 +67,7 @@
 #endif
 
 #ifndef set_mb
-#define set_mb(var, value)  do { (var) = (value); mb(); } while (0)
+#define set_mb(var, value)  do { WRITE_ONCE(var, value); mb(); } while (0)
 #endif
 
 #ifndef smp_mb__before_atomic
index a7c0941d10da741c8241bdd3125eaaad4ad9f52e..03e227ba481c419ab468d697469a4418eec9f48f 100644 (file)
@@ -250,7 +250,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
        ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
 
 #define WRITE_ONCE(x, val) \
-       ({ typeof(x) __val = (val); __write_once_size(&(x), &__val, sizeof(__val)); __val; })
+       ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
 
 #endif /* __KERNEL__ */