diff options
| author | Ivan Kokshaysky <ink@jurassic.park.msu.ru> | 2005-10-21 14:06:15 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-22 22:38:33 -0400 |
| commit | d475f3f47a0427dfee483cecf9a7e9109e991423 (patch) | |
| tree | bbaa882b849acf13e624e3e1d8f4d31280a4b74b | |
| parent | 4595f251058609d97a5d792de08c34a7956af816 (diff) | |
[PATCH] alpha: additional smp barriers
As stated in Documentation/atomic_ops.txt, atomic functions
returning values must have the memory barriers both before and after
the operation.
Thanks to DaveM for pointing that out.
Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | include/asm-alpha/atomic.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index 1b383e3cb68c..0b40bad00289 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h | |||
| @@ -100,18 +100,19 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) | |||
| 100 | static __inline__ long atomic_add_return(int i, atomic_t * v) | 100 | static __inline__ long atomic_add_return(int i, atomic_t * v) |
| 101 | { | 101 | { |
| 102 | long temp, result; | 102 | long temp, result; |
| 103 | smp_mb(); | ||
| 103 | __asm__ __volatile__( | 104 | __asm__ __volatile__( |
| 104 | "1: ldl_l %0,%1\n" | 105 | "1: ldl_l %0,%1\n" |
| 105 | " addl %0,%3,%2\n" | 106 | " addl %0,%3,%2\n" |
| 106 | " addl %0,%3,%0\n" | 107 | " addl %0,%3,%0\n" |
| 107 | " stl_c %0,%1\n" | 108 | " stl_c %0,%1\n" |
| 108 | " beq %0,2f\n" | 109 | " beq %0,2f\n" |
| 109 | " mb\n" | ||
| 110 | ".subsection 2\n" | 110 | ".subsection 2\n" |
| 111 | "2: br 1b\n" | 111 | "2: br 1b\n" |
| 112 | ".previous" | 112 | ".previous" |
| 113 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) | 113 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) |
| 114 | :"Ir" (i), "m" (v->counter) : "memory"); | 114 | :"Ir" (i), "m" (v->counter) : "memory"); |
| 115 | smp_mb(); | ||
| 115 | return result; | 116 | return result; |
| 116 | } | 117 | } |
| 117 | 118 | ||
| @@ -120,54 +121,57 @@ static __inline__ long atomic_add_return(int i, atomic_t * v) | |||
| 120 | static __inline__ long atomic64_add_return(long i, atomic64_t * v) | 121 | static __inline__ long atomic64_add_return(long i, atomic64_t * v) |
| 121 | { | 122 | { |
| 122 | long temp, result; | 123 | long temp, result; |
| 124 | smp_mb(); | ||
| 123 | __asm__ __volatile__( | 125 | __asm__ __volatile__( |
| 124 | "1: ldq_l %0,%1\n" | 126 | "1: ldq_l %0,%1\n" |
| 125 | " addq %0,%3,%2\n" | 127 | " addq %0,%3,%2\n" |
| 126 | " addq %0,%3,%0\n" | 128 | " addq %0,%3,%0\n" |
| 127 | " stq_c %0,%1\n" | 129 | " stq_c %0,%1\n" |
| 128 | " beq %0,2f\n" | 130 | " beq %0,2f\n" |
| 129 | " mb\n" | ||
| 130 | ".subsection 2\n" | 131 | ".subsection 2\n" |
| 131 | "2: br 1b\n" | 132 | "2: br 1b\n" |
| 132 | ".previous" | 133 | ".previous" |
| 133 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) | 134 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) |
| 134 | :"Ir" (i), "m" (v->counter) : "memory"); | 135 | :"Ir" (i), "m" (v->counter) : "memory"); |
| 136 | smp_mb(); | ||
| 135 | return result; | 137 | return result; |
| 136 | } | 138 | } |
| 137 | 139 | ||
| 138 | static __inline__ long atomic_sub_return(int i, atomic_t * v) | 140 | static __inline__ long atomic_sub_return(int i, atomic_t * v) |
| 139 | { | 141 | { |
| 140 | long temp, result; | 142 | long temp, result; |
| 143 | smp_mb(); | ||
| 141 | __asm__ __volatile__( | 144 | __asm__ __volatile__( |
| 142 | "1: ldl_l %0,%1\n" | 145 | "1: ldl_l %0,%1\n" |
| 143 | " subl %0,%3,%2\n" | 146 | " subl %0,%3,%2\n" |
| 144 | " subl %0,%3,%0\n" | 147 | " subl %0,%3,%0\n" |
| 145 | " stl_c %0,%1\n" | 148 | " stl_c %0,%1\n" |
| 146 | " beq %0,2f\n" | 149 | " beq %0,2f\n" |
| 147 | " mb\n" | ||
| 148 | ".subsection 2\n" | 150 | ".subsection 2\n" |
| 149 | "2: br 1b\n" | 151 | "2: br 1b\n" |
| 150 | ".previous" | 152 | ".previous" |
| 151 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) | 153 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) |
| 152 | :"Ir" (i), "m" (v->counter) : "memory"); | 154 | :"Ir" (i), "m" (v->counter) : "memory"); |
| 155 | smp_mb(); | ||
| 153 | return result; | 156 | return result; |
| 154 | } | 157 | } |
| 155 | 158 | ||
| 156 | static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | 159 | static __inline__ long atomic64_sub_return(long i, atomic64_t * v) |
| 157 | { | 160 | { |
| 158 | long temp, result; | 161 | long temp, result; |
| 162 | smp_mb(); | ||
| 159 | __asm__ __volatile__( | 163 | __asm__ __volatile__( |
| 160 | "1: ldq_l %0,%1\n" | 164 | "1: ldq_l %0,%1\n" |
| 161 | " subq %0,%3,%2\n" | 165 | " subq %0,%3,%2\n" |
| 162 | " subq %0,%3,%0\n" | 166 | " subq %0,%3,%0\n" |
| 163 | " stq_c %0,%1\n" | 167 | " stq_c %0,%1\n" |
| 164 | " beq %0,2f\n" | 168 | " beq %0,2f\n" |
| 165 | " mb\n" | ||
| 166 | ".subsection 2\n" | 169 | ".subsection 2\n" |
| 167 | "2: br 1b\n" | 170 | "2: br 1b\n" |
| 168 | ".previous" | 171 | ".previous" |
| 169 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) | 172 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) |
| 170 | :"Ir" (i), "m" (v->counter) : "memory"); | 173 | :"Ir" (i), "m" (v->counter) : "memory"); |
| 174 | smp_mb(); | ||
| 171 | return result; | 175 | return result; |
| 172 | } | 176 | } |
| 173 | 177 | ||
