aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:48:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:48:00 -0400
commitdbb885fecc1b1b35e93416bedd24d21bd20f60ed (patch)
tree9aa92bcc4e3d3594eba0ba85d72b878d85f35a59 /arch/alpha
parentd6dd50e07c5bec00db2005969b1a01f8ca3d25ef (diff)
parent2291059c852706c6f5ffb400366042b7625066cd (diff)
Merge branch 'locking-arch-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull arch atomic cleanups from Ingo Molnar: "This is a series kept separate from the main locking tree, which cleans up and improves various details in the atomics type handling: - Remove the unused atomic_or_long() method - Consolidate and compress atomic ops implementations between architectures, to reduce linecount and to make it easier to add new ops. - Rewrite generic atomic support to only require cmpxchg() from an architecture - generate all other methods from that" * 'locking-arch-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) locking,arch: Use ACCESS_ONCE() instead of cast to volatile in atomic_read() locking, mips: Fix atomics locking, sparc64: Fix atomics locking,arch: Rewrite generic atomic support locking,arch,xtensa: Fold atomic_ops locking,arch,sparc: Fold atomic_ops locking,arch,sh: Fold atomic_ops locking,arch,powerpc: Fold atomic_ops locking,arch,parisc: Fold atomic_ops locking,arch,mn10300: Fold atomic_ops locking,arch,mips: Fold atomic_ops locking,arch,metag: Fold atomic_ops locking,arch,m68k: Fold atomic_ops locking,arch,m32r: Fold atomic_ops locking,arch,ia64: Fold atomic_ops locking,arch,hexagon: Fold atomic_ops locking,arch,cris: Fold atomic_ops locking,arch,avr32: Fold atomic_ops locking,arch,arm64: Fold atomic_ops locking,arch,arm: Fold atomic_ops ...
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/include/asm/atomic.h217
1 files changed, 82 insertions, 135 deletions
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
index ed60a1ee1ed3..8f8eafbedd7c 100644
--- a/arch/alpha/include/asm/atomic.h
+++ b/arch/alpha/include/asm/atomic.h
@@ -17,8 +17,8 @@
17#define ATOMIC_INIT(i) { (i) } 17#define ATOMIC_INIT(i) { (i) }
18#define ATOMIC64_INIT(i) { (i) } 18#define ATOMIC64_INIT(i) { (i) }
19 19
20#define atomic_read(v) (*(volatile int *)&(v)->counter) 20#define atomic_read(v) ACCESS_ONCE((v)->counter)
21#define atomic64_read(v) (*(volatile long *)&(v)->counter) 21#define atomic64_read(v) ACCESS_ONCE((v)->counter)
22 22
23#define atomic_set(v,i) ((v)->counter = (i)) 23#define atomic_set(v,i) ((v)->counter = (i))
24#define atomic64_set(v,i) ((v)->counter = (i)) 24#define atomic64_set(v,i) ((v)->counter = (i))
@@ -29,145 +29,92 @@
29 * branch back to restart the operation. 29 * branch back to restart the operation.
30 */ 30 */
31 31
32static __inline__ void atomic_add(int i, atomic_t * v) 32#define ATOMIC_OP(op) \
33{ 33static __inline__ void atomic_##op(int i, atomic_t * v) \
34 unsigned long temp; 34{ \
35 __asm__ __volatile__( 35 unsigned long temp; \
36 "1: ldl_l %0,%1\n" 36 __asm__ __volatile__( \
37 " addl %0,%2,%0\n" 37 "1: ldl_l %0,%1\n" \
38 " stl_c %0,%1\n" 38 " " #op "l %0,%2,%0\n" \
39 " beq %0,2f\n" 39 " stl_c %0,%1\n" \
40 ".subsection 2\n" 40 " beq %0,2f\n" \
41 "2: br 1b\n" 41 ".subsection 2\n" \
42 ".previous" 42 "2: br 1b\n" \
43 :"=&r" (temp), "=m" (v->counter) 43 ".previous" \
44 :"Ir" (i), "m" (v->counter)); 44 :"=&r" (temp), "=m" (v->counter) \
45} 45 :"Ir" (i), "m" (v->counter)); \
46 46} \
47static __inline__ void atomic64_add(long i, atomic64_t * v) 47
48{ 48#define ATOMIC_OP_RETURN(op) \
49 unsigned long temp; 49static inline int atomic_##op##_return(int i, atomic_t *v) \
50 __asm__ __volatile__( 50{ \
51 "1: ldq_l %0,%1\n" 51 long temp, result; \
52 " addq %0,%2,%0\n" 52 smp_mb(); \
53 " stq_c %0,%1\n" 53 __asm__ __volatile__( \
54 " beq %0,2f\n" 54 "1: ldl_l %0,%1\n" \
55 ".subsection 2\n" 55 " " #op "l %0,%3,%2\n" \
56 "2: br 1b\n" 56 " " #op "l %0,%3,%0\n" \
57 ".previous" 57 " stl_c %0,%1\n" \
58 :"=&r" (temp), "=m" (v->counter) 58 " beq %0,2f\n" \
59 :"Ir" (i), "m" (v->counter)); 59 ".subsection 2\n" \
60} 60 "2: br 1b\n" \
61 61 ".previous" \
62static __inline__ void atomic_sub(int i, atomic_t * v) 62 :"=&r" (temp), "=m" (v->counter), "=&r" (result) \
63{ 63 :"Ir" (i), "m" (v->counter) : "memory"); \
64 unsigned long temp; 64 smp_mb(); \
65 __asm__ __volatile__( 65 return result; \
66 "1: ldl_l %0,%1\n"
67 " subl %0,%2,%0\n"
68 " stl_c %0,%1\n"
69 " beq %0,2f\n"
70 ".subsection 2\n"
71 "2: br 1b\n"
72 ".previous"
73 :"=&r" (temp), "=m" (v->counter)
74 :"Ir" (i), "m" (v->counter));
75} 66}
76 67
77static __inline__ void atomic64_sub(long i, atomic64_t * v) 68#define ATOMIC64_OP(op) \
78{ 69static __inline__ void atomic64_##op(long i, atomic64_t * v) \
79 unsigned long temp; 70{ \
80 __asm__ __volatile__( 71 unsigned long temp; \
81 "1: ldq_l %0,%1\n" 72 __asm__ __volatile__( \
82 " subq %0,%2,%0\n" 73 "1: ldq_l %0,%1\n" \
83 " stq_c %0,%1\n" 74 " " #op "q %0,%2,%0\n" \
84 " beq %0,2f\n" 75 " stq_c %0,%1\n" \
85 ".subsection 2\n" 76 " beq %0,2f\n" \
86 "2: br 1b\n" 77 ".subsection 2\n" \
87 ".previous" 78 "2: br 1b\n" \
88 :"=&r" (temp), "=m" (v->counter) 79 ".previous" \
89 :"Ir" (i), "m" (v->counter)); 80 :"=&r" (temp), "=m" (v->counter) \
90} 81 :"Ir" (i), "m" (v->counter)); \
91 82} \
92 83
93/* 84#define ATOMIC64_OP_RETURN(op) \
94 * Same as above, but return the result value 85static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
95 */ 86{ \
96static inline int atomic_add_return(int i, atomic_t *v) 87 long temp, result; \
97{ 88 smp_mb(); \
98 long temp, result; 89 __asm__ __volatile__( \
99 smp_mb(); 90 "1: ldq_l %0,%1\n" \
100 __asm__ __volatile__( 91 " " #op "q %0,%3,%2\n" \
101 "1: ldl_l %0,%1\n" 92 " " #op "q %0,%3,%0\n" \
102 " addl %0,%3,%2\n" 93 " stq_c %0,%1\n" \
103 " addl %0,%3,%0\n" 94 " beq %0,2f\n" \
104 " stl_c %0,%1\n" 95 ".subsection 2\n" \
105 " beq %0,2f\n" 96 "2: br 1b\n" \
106 ".subsection 2\n" 97 ".previous" \
107 "2: br 1b\n" 98 :"=&r" (temp), "=m" (v->counter), "=&r" (result) \
108 ".previous" 99 :"Ir" (i), "m" (v->counter) : "memory"); \
109 :"=&r" (temp), "=m" (v->counter), "=&r" (result) 100 smp_mb(); \
110 :"Ir" (i), "m" (v->counter) : "memory"); 101 return result; \
111 smp_mb();
112 return result;
113} 102}
114 103
115static __inline__ long atomic64_add_return(long i, atomic64_t * v) 104#define ATOMIC_OPS(opg) \
116{ 105 ATOMIC_OP(opg) \
117 long temp, result; 106 ATOMIC_OP_RETURN(opg) \
118 smp_mb(); 107 ATOMIC64_OP(opg) \
119 __asm__ __volatile__( 108 ATOMIC64_OP_RETURN(opg)
120 "1: ldq_l %0,%1\n"
121 " addq %0,%3,%2\n"
122 " addq %0,%3,%0\n"
123 " stq_c %0,%1\n"
124 " beq %0,2f\n"
125 ".subsection 2\n"
126 "2: br 1b\n"
127 ".previous"
128 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
129 :"Ir" (i), "m" (v->counter) : "memory");
130 smp_mb();
131 return result;
132}
133 109
134static __inline__ long atomic_sub_return(int i, atomic_t * v) 110ATOMIC_OPS(add)
135{ 111ATOMIC_OPS(sub)
136 long temp, result;
137 smp_mb();
138 __asm__ __volatile__(
139 "1: ldl_l %0,%1\n"
140 " subl %0,%3,%2\n"
141 " subl %0,%3,%0\n"
142 " stl_c %0,%1\n"
143 " beq %0,2f\n"
144 ".subsection 2\n"
145 "2: br 1b\n"
146 ".previous"
147 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
148 :"Ir" (i), "m" (v->counter) : "memory");
149 smp_mb();
150 return result;
151}
152 112
153static __inline__ long atomic64_sub_return(long i, atomic64_t * v) 113#undef ATOMIC_OPS
154{ 114#undef ATOMIC64_OP_RETURN
155 long temp, result; 115#undef ATOMIC64_OP
156 smp_mb(); 116#undef ATOMIC_OP_RETURN
157 __asm__ __volatile__( 117#undef ATOMIC_OP
158 "1: ldq_l %0,%1\n"
159 " subq %0,%3,%2\n"
160 " subq %0,%3,%0\n"
161 " stq_c %0,%1\n"
162 " beq %0,2f\n"
163 ".subsection 2\n"
164 "2: br 1b\n"
165 ".previous"
166 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
167 :"Ir" (i), "m" (v->counter) : "memory");
168 smp_mb();
169 return result;
170}
171 118
172#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) 119#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
173#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) 120#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))