diff options
| -rw-r--r-- | arch/alpha/include/asm/xchg.h | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h index e1facf6fc244..e2b59fac5257 100644 --- a/arch/alpha/include/asm/xchg.h +++ b/arch/alpha/include/asm/xchg.h | |||
| @@ -12,6 +12,10 @@ | |||
| 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 | * | ||
| 15 | */ | 19 | */ |
| 16 | 20 | ||
| 17 | static inline unsigned long | 21 | static inline unsigned long |
| @@ -19,6 +23,7 @@ ____xchg(_u8, volatile char *m, unsigned long val) | |||
| 19 | { | 23 | { |
| 20 | unsigned long ret, tmp, addr64; | 24 | unsigned long ret, tmp, addr64; |
| 21 | 25 | ||
| 26 | smp_mb(); | ||
| 22 | __asm__ __volatile__( | 27 | __asm__ __volatile__( |
| 23 | " andnot %4,7,%3\n" | 28 | " andnot %4,7,%3\n" |
| 24 | " insbl %1,%4,%1\n" | 29 | " insbl %1,%4,%1\n" |
| @@ -43,6 +48,7 @@ ____xchg(_u16, volatile short *m, unsigned long val) | |||
| 43 | { | 48 | { |
| 44 | unsigned long ret, tmp, addr64; | 49 | unsigned long ret, tmp, addr64; |
| 45 | 50 | ||
| 51 | smp_mb(); | ||
| 46 | __asm__ __volatile__( | 52 | __asm__ __volatile__( |
| 47 | " andnot %4,7,%3\n" | 53 | " andnot %4,7,%3\n" |
| 48 | " inswl %1,%4,%1\n" | 54 | " inswl %1,%4,%1\n" |
| @@ -67,6 +73,7 @@ ____xchg(_u32, volatile int *m, unsigned long val) | |||
| 67 | { | 73 | { |
| 68 | unsigned long dummy; | 74 | unsigned long dummy; |
| 69 | 75 | ||
| 76 | smp_mb(); | ||
| 70 | __asm__ __volatile__( | 77 | __asm__ __volatile__( |
| 71 | "1: ldl_l %0,%4\n" | 78 | "1: ldl_l %0,%4\n" |
| 72 | " bis $31,%3,%1\n" | 79 | " bis $31,%3,%1\n" |
| @@ -87,6 +94,7 @@ ____xchg(_u64, volatile long *m, unsigned long val) | |||
| 87 | { | 94 | { |
| 88 | unsigned long dummy; | 95 | unsigned long dummy; |
| 89 | 96 | ||
| 97 | smp_mb(); | ||
| 90 | __asm__ __volatile__( | 98 | __asm__ __volatile__( |
| 91 | "1: ldq_l %0,%4\n" | 99 | "1: ldq_l %0,%4\n" |
| 92 | " bis $31,%3,%1\n" | 100 | " bis $31,%3,%1\n" |
| @@ -128,9 +136,12 @@ ____xchg(, volatile void *ptr, unsigned long x, int size) | |||
| 128 | * store NEW in MEM. Return the initial value in MEM. Success is | 136 | * store NEW in MEM. Return the initial value in MEM. Success is |
| 129 | * indicated by comparing RETURN with OLD. | 137 | * indicated by comparing RETURN with OLD. |
| 130 | * | 138 | * |
| 131 | * The memory barrier is placed in SMP unconditionally, in order to | 139 | * The leading and the trailing memory barriers guarantee that these |
| 132 | * guarantee that dependency ordering is preserved when a dependency | 140 | * operations are fully ordered. |
| 133 | * is headed by an unsuccessful operation. | 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. | ||
| 134 | */ | 145 | */ |
| 135 | 146 | ||
| 136 | static inline unsigned long | 147 | static inline unsigned long |
| @@ -138,6 +149,7 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new) | |||
| 138 | { | 149 | { |
| 139 | unsigned long prev, tmp, cmp, addr64; | 150 | unsigned long prev, tmp, cmp, addr64; |
| 140 | 151 | ||
| 152 | smp_mb(); | ||
| 141 | __asm__ __volatile__( | 153 | __asm__ __volatile__( |
| 142 | " andnot %5,7,%4\n" | 154 | " andnot %5,7,%4\n" |
| 143 | " insbl %1,%5,%1\n" | 155 | " insbl %1,%5,%1\n" |
| @@ -165,6 +177,7 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new) | |||
| 165 | { | 177 | { |
| 166 | unsigned long prev, tmp, cmp, addr64; | 178 | unsigned long prev, tmp, cmp, addr64; |
| 167 | 179 | ||
| 180 | smp_mb(); | ||
| 168 | __asm__ __volatile__( | 181 | __asm__ __volatile__( |
| 169 | " andnot %5,7,%4\n" | 182 | " andnot %5,7,%4\n" |
| 170 | " inswl %1,%5,%1\n" | 183 | " inswl %1,%5,%1\n" |
| @@ -192,6 +205,7 @@ ____cmpxchg(_u32, volatile int *m, int old, int new) | |||
| 192 | { | 205 | { |
| 193 | unsigned long prev, cmp; | 206 | unsigned long prev, cmp; |
| 194 | 207 | ||
| 208 | smp_mb(); | ||
| 195 | __asm__ __volatile__( | 209 | __asm__ __volatile__( |
| 196 | "1: ldl_l %0,%5\n" | 210 | "1: ldl_l %0,%5\n" |
| 197 | " cmpeq %0,%3,%1\n" | 211 | " cmpeq %0,%3,%1\n" |
| @@ -215,6 +229,7 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new) | |||
| 215 | { | 229 | { |
| 216 | unsigned long prev, cmp; | 230 | unsigned long prev, cmp; |
| 217 | 231 | ||
| 232 | smp_mb(); | ||
| 218 | __asm__ __volatile__( | 233 | __asm__ __volatile__( |
| 219 | "1: ldq_l %0,%5\n" | 234 | "1: ldq_l %0,%5\n" |
| 220 | " cmpeq %0,%3,%1\n" | 235 | " cmpeq %0,%3,%1\n" |
