aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Parri <parri.andrea@gmail.com>2018-02-26 23:00:58 -0500
committerIngo Molnar <mingo@kernel.org>2018-03-12 05:59:03 -0400
commitfbfcd0199170984bd3c2812e49ed0fe7b226959a (patch)
treea17482251a965cb047cda3d91bbc4810aeb3a48b
parentbd5c0ba2cd78a4c116726ead84f8f37dc92d043e (diff)
locking/xchg/alpha: Remove superfluous memory barriers from the _local() variants
The following two commits: 79d442461df74 ("locking/xchg/alpha: Clean up barrier usage by using smp_mb() in place of __ASM__MB") 472e8c55cf662 ("locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs") ... ended up adding unnecessary barriers to the _local() variants on Alpha, which the previous code took care to avoid. Fix them by adding the smp_mb() into the cmpxchg() macro rather than into the ____cmpxchg() variants. Reported-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Turner <mattst88@gmail.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Richard Henderson <rth@twiddle.net> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-alpha@vger.kernel.org Fixes: 472e8c55cf662 ("locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs") Fixes: 79d442461df74 ("locking/xchg/alpha: Clean up barrier usage by using smp_mb() in place of __ASM__MB") Link: http://lkml.kernel.org/r/1519704058-13430-1-git-send-email-parri.andrea@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/alpha/include/asm/cmpxchg.h20
-rw-r--r--arch/alpha/include/asm/xchg.h27
2 files changed, 16 insertions, 31 deletions
diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h
index 8a2b331e43fe..6c7c39452471 100644
--- a/arch/alpha/include/asm/cmpxchg.h
+++ b/arch/alpha/include/asm/cmpxchg.h
@@ -38,19 +38,31 @@
38#define ____cmpxchg(type, args...) __cmpxchg ##type(args) 38#define ____cmpxchg(type, args...) __cmpxchg ##type(args)
39#include <asm/xchg.h> 39#include <asm/xchg.h>
40 40
41/*
42 * The leading and the trailing memory barriers guarantee that these
43 * operations are fully ordered.
44 */
41#define xchg(ptr, x) \ 45#define xchg(ptr, x) \
42({ \ 46({ \
47 __typeof__(*(ptr)) __ret; \
43 __typeof__(*(ptr)) _x_ = (x); \ 48 __typeof__(*(ptr)) _x_ = (x); \
44 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ 49 smp_mb(); \
45 sizeof(*(ptr))); \ 50 __ret = (__typeof__(*(ptr))) \
51 __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
52 smp_mb(); \
53 __ret; \
46}) 54})
47 55
48#define cmpxchg(ptr, o, n) \ 56#define cmpxchg(ptr, o, n) \
49({ \ 57({ \
58 __typeof__(*(ptr)) __ret; \
50 __typeof__(*(ptr)) _o_ = (o); \ 59 __typeof__(*(ptr)) _o_ = (o); \
51 __typeof__(*(ptr)) _n_ = (n); \ 60 __typeof__(*(ptr)) _n_ = (n); \
52 (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ 61 smp_mb(); \
53 (unsigned long)_n_, sizeof(*(ptr)));\ 62 __ret = (__typeof__(*(ptr))) __cmpxchg((ptr), \
63 (unsigned long)_o_, (unsigned long)_n_, sizeof(*(ptr)));\
64 smp_mb(); \
65 __ret; \
54}) 66})
55 67
56#define cmpxchg64(ptr, o, n) \ 68#define cmpxchg64(ptr, o, n) \
diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h
index e2b59fac5257..7adb80c6746a 100644
--- a/arch/alpha/include/asm/xchg.h
+++ b/arch/alpha/include/asm/xchg.h
@@ -12,10 +12,6 @@
12 * Atomic exchange. 12 * Atomic exchange.
13 * Since it can be used to implement critical sections 13 * Since it can be used to implement critical sections
14 * it must clobber "memory" (also for interrupts in UP). 14 * it must clobber "memory" (also for interrupts in UP).
15 *
16 * The leading and the trailing memory barriers guarantee that these
17 * operations are fully ordered.
18 *
19 */ 15 */
20 16
21static inline unsigned long 17static inline unsigned long
@@ -23,7 +19,6 @@ ____xchg(_u8, volatile char *m, unsigned long val)
23{ 19{
24 unsigned long ret, tmp, addr64; 20 unsigned long ret, tmp, addr64;
25 21
26 smp_mb();
27 __asm__ __volatile__( 22 __asm__ __volatile__(
28 " andnot %4,7,%3\n" 23 " andnot %4,7,%3\n"
29 " insbl %1,%4,%1\n" 24 " insbl %1,%4,%1\n"
@@ -38,7 +33,6 @@ ____xchg(_u8, volatile char *m, unsigned long val)
38 ".previous" 33 ".previous"
39 : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) 34 : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
40 : "r" ((long)m), "1" (val) : "memory"); 35 : "r" ((long)m), "1" (val) : "memory");
41 smp_mb();
42 36
43 return ret; 37 return ret;
44} 38}
@@ -48,7 +42,6 @@ ____xchg(_u16, volatile short *m, unsigned long val)
48{ 42{
49 unsigned long ret, tmp, addr64; 43 unsigned long ret, tmp, addr64;
50 44
51 smp_mb();
52 __asm__ __volatile__( 45 __asm__ __volatile__(
53 " andnot %4,7,%3\n" 46 " andnot %4,7,%3\n"
54 " inswl %1,%4,%1\n" 47 " inswl %1,%4,%1\n"
@@ -63,7 +56,6 @@ ____xchg(_u16, volatile short *m, unsigned long val)
63 ".previous" 56 ".previous"
64 : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) 57 : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
65 : "r" ((long)m), "1" (val) : "memory"); 58 : "r" ((long)m), "1" (val) : "memory");
66 smp_mb();
67 59
68 return ret; 60 return ret;
69} 61}
@@ -73,7 +65,6 @@ ____xchg(_u32, volatile int *m, unsigned long val)
73{ 65{
74 unsigned long dummy; 66 unsigned long dummy;
75 67
76 smp_mb();
77 __asm__ __volatile__( 68 __asm__ __volatile__(
78 "1: ldl_l %0,%4\n" 69 "1: ldl_l %0,%4\n"
79 " bis $31,%3,%1\n" 70 " bis $31,%3,%1\n"
@@ -84,7 +75,6 @@ ____xchg(_u32, volatile int *m, unsigned long val)
84 ".previous" 75 ".previous"
85 : "=&r" (val), "=&r" (dummy), "=m" (*m) 76 : "=&r" (val), "=&r" (dummy), "=m" (*m)
86 : "rI" (val), "m" (*m) : "memory"); 77 : "rI" (val), "m" (*m) : "memory");
87 smp_mb();
88 78
89 return val; 79 return val;
90} 80}
@@ -94,7 +84,6 @@ ____xchg(_u64, volatile long *m, unsigned long val)
94{ 84{
95 unsigned long dummy; 85 unsigned long dummy;
96 86
97 smp_mb();
98 __asm__ __volatile__( 87 __asm__ __volatile__(
99 "1: ldq_l %0,%4\n" 88 "1: ldq_l %0,%4\n"
100 " bis $31,%3,%1\n" 89 " bis $31,%3,%1\n"
@@ -105,7 +94,6 @@ ____xchg(_u64, volatile long *m, unsigned long val)
105 ".previous" 94 ".previous"
106 : "=&r" (val), "=&r" (dummy), "=m" (*m) 95 : "=&r" (val), "=&r" (dummy), "=m" (*m)
107 : "rI" (val), "m" (*m) : "memory"); 96 : "rI" (val), "m" (*m) : "memory");
108 smp_mb();
109 97
110 return val; 98 return val;
111} 99}
@@ -135,13 +123,6 @@ ____xchg(, volatile void *ptr, unsigned long x, int size)
135 * Atomic compare and exchange. Compare OLD with MEM, if identical, 123 * Atomic compare and exchange. Compare OLD with MEM, if identical,
136 * store NEW in MEM. Return the initial value in MEM. Success is 124 * store NEW in MEM. Return the initial value in MEM. Success is
137 * indicated by comparing RETURN with OLD. 125 * indicated by comparing RETURN with OLD.
138 *
139 * The leading and the trailing memory barriers guarantee that these
140 * operations are fully ordered.
141 *
142 * The trailing memory barrier is placed in SMP unconditionally, in
143 * order to guarantee that dependency ordering is preserved when a
144 * dependency is headed by an unsuccessful operation.
145 */ 126 */
146 127
147static inline unsigned long 128static inline unsigned long
@@ -149,7 +130,6 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
149{ 130{
150 unsigned long prev, tmp, cmp, addr64; 131 unsigned long prev, tmp, cmp, addr64;
151 132
152 smp_mb();
153 __asm__ __volatile__( 133 __asm__ __volatile__(
154 " andnot %5,7,%4\n" 134 " andnot %5,7,%4\n"
155 " insbl %1,%5,%1\n" 135 " insbl %1,%5,%1\n"
@@ -167,7 +147,6 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
167 ".previous" 147 ".previous"
168 : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) 148 : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
169 : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); 149 : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
170 smp_mb();
171 150
172 return prev; 151 return prev;
173} 152}
@@ -177,7 +156,6 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
177{ 156{
178 unsigned long prev, tmp, cmp, addr64; 157 unsigned long prev, tmp, cmp, addr64;
179 158
180 smp_mb();
181 __asm__ __volatile__( 159 __asm__ __volatile__(
182 " andnot %5,7,%4\n" 160 " andnot %5,7,%4\n"
183 " inswl %1,%5,%1\n" 161 " inswl %1,%5,%1\n"
@@ -195,7 +173,6 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
195 ".previous" 173 ".previous"
196 : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) 174 : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
197 : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); 175 : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
198 smp_mb();
199 176
200 return prev; 177 return prev;
201} 178}
@@ -205,7 +182,6 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
205{ 182{
206 unsigned long prev, cmp; 183 unsigned long prev, cmp;
207 184
208 smp_mb();
209 __asm__ __volatile__( 185 __asm__ __volatile__(
210 "1: ldl_l %0,%5\n" 186 "1: ldl_l %0,%5\n"
211 " cmpeq %0,%3,%1\n" 187 " cmpeq %0,%3,%1\n"
@@ -219,7 +195,6 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
219 ".previous" 195 ".previous"
220 : "=&r"(prev), "=&r"(cmp), "=m"(*m) 196 : "=&r"(prev), "=&r"(cmp), "=m"(*m)
221 : "r"((long) old), "r"(new), "m"(*m) : "memory"); 197 : "r"((long) old), "r"(new), "m"(*m) : "memory");
222 smp_mb();
223 198
224 return prev; 199 return prev;
225} 200}
@@ -229,7 +204,6 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
229{ 204{
230 unsigned long prev, cmp; 205 unsigned long prev, cmp;
231 206
232 smp_mb();
233 __asm__ __volatile__( 207 __asm__ __volatile__(
234 "1: ldq_l %0,%5\n" 208 "1: ldq_l %0,%5\n"
235 " cmpeq %0,%3,%1\n" 209 " cmpeq %0,%3,%1\n"
@@ -243,7 +217,6 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
243 ".previous" 217 ".previous"
244 : "=&r"(prev), "=&r"(cmp), "=m"(*m) 218 : "=&r"(prev), "=&r"(cmp), "=m"(*m)
245 : "r"((long) old), "r"(new), "m"(*m) : "memory"); 219 : "r"((long) old), "r"(new), "m"(*m) : "memory");
246 smp_mb();
247 220
248 return prev; 221 return prev;
249} 222}