xref: /OK3568_Linux_fs/kernel/Documentation/atomic_t.txt (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun
2*4882a593SmuzhiyunOn atomic types (atomic_t atomic64_t and atomic_long_t).
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunThe atomic type provides an interface to the architecture's means of atomic
5*4882a593SmuzhiyunRMW operations between CPUs (atomic operations on MMIO are not supported and
6*4882a593Smuzhiyuncan lead to fatal traps on some platforms).
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunAPI
9*4882a593Smuzhiyun---
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunThe 'full' API consists of (atomic64_ and atomic_long_ prefixes omitted for
12*4882a593Smuzhiyunbrevity):
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunNon-RMW ops:
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun  atomic_read(), atomic_set()
17*4882a593Smuzhiyun  atomic_read_acquire(), atomic_set_release()
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunRMW atomic operations:
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunArithmetic:
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun  atomic_{add,sub,inc,dec}()
25*4882a593Smuzhiyun  atomic_{add,sub,inc,dec}_return{,_relaxed,_acquire,_release}()
26*4882a593Smuzhiyun  atomic_fetch_{add,sub,inc,dec}{,_relaxed,_acquire,_release}()
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunBitwise:
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun  atomic_{and,or,xor,andnot}()
32*4882a593Smuzhiyun  atomic_fetch_{and,or,xor,andnot}{,_relaxed,_acquire,_release}()
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun
35*4882a593SmuzhiyunSwap:
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun  atomic_xchg{,_relaxed,_acquire,_release}()
38*4882a593Smuzhiyun  atomic_cmpxchg{,_relaxed,_acquire,_release}()
39*4882a593Smuzhiyun  atomic_try_cmpxchg{,_relaxed,_acquire,_release}()
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun
42*4882a593SmuzhiyunReference count (but please see refcount_t):
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun  atomic_add_unless(), atomic_inc_not_zero()
45*4882a593Smuzhiyun  atomic_sub_and_test(), atomic_dec_and_test()
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun
48*4882a593SmuzhiyunMisc:
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun  atomic_inc_and_test(), atomic_add_negative()
51*4882a593Smuzhiyun  atomic_dec_unless_positive(), atomic_inc_unless_negative()
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun
54*4882a593SmuzhiyunBarriers:
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun  smp_mb__{before,after}_atomic()
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun
59*4882a593SmuzhiyunTYPES (signed vs unsigned)
60*4882a593Smuzhiyun-----
61*4882a593Smuzhiyun
62*4882a593SmuzhiyunWhile atomic_t, atomic_long_t and atomic64_t use int, long and s64
63*4882a593Smuzhiyunrespectively (for hysterical raisins), the kernel uses -fno-strict-overflow
64*4882a593Smuzhiyun(which implies -fwrapv) and defines signed overflow to behave like
65*4882a593Smuzhiyun2s-complement.
66*4882a593Smuzhiyun
67*4882a593SmuzhiyunTherefore, an explicitly unsigned variant of the atomic ops is strictly
68*4882a593Smuzhiyununnecessary and we can simply cast, there is no UB.
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunThere was a bug in UBSAN prior to GCC-8 that would generate UB warnings for
71*4882a593Smuzhiyunsigned types.
72*4882a593Smuzhiyun
73*4882a593SmuzhiyunWith this we also conform to the C/C++ _Atomic behaviour and things like
74*4882a593SmuzhiyunP1236R1.
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun
77*4882a593SmuzhiyunSEMANTICS
78*4882a593Smuzhiyun---------
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunNon-RMW ops:
81*4882a593Smuzhiyun
82*4882a593SmuzhiyunThe non-RMW ops are (typically) regular LOADs and STOREs and are canonically
83*4882a593Smuzhiyunimplemented using READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and
84*4882a593Smuzhiyunsmp_store_release() respectively. Therefore, if you find yourself only using
85*4882a593Smuzhiyunthe Non-RMW operations of atomic_t, you do not in fact need atomic_t at all
86*4882a593Smuzhiyunand are doing it wrong.
87*4882a593Smuzhiyun
88*4882a593SmuzhiyunA note for the implementation of atomic_set{}() is that it must not break the
89*4882a593Smuzhiyunatomicity of the RMW ops. That is:
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun  C Atomic-RMW-ops-are-atomic-WRT-atomic_set
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun  {
94*4882a593Smuzhiyun    atomic_t v = ATOMIC_INIT(1);
95*4882a593Smuzhiyun  }
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun  P0(atomic_t *v)
98*4882a593Smuzhiyun  {
99*4882a593Smuzhiyun    (void)atomic_add_unless(v, 1, 0);
100*4882a593Smuzhiyun  }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun  P1(atomic_t *v)
103*4882a593Smuzhiyun  {
104*4882a593Smuzhiyun    atomic_set(v, 0);
105*4882a593Smuzhiyun  }
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun  exists
108*4882a593Smuzhiyun  (v=2)
109*4882a593Smuzhiyun
110*4882a593SmuzhiyunIn this case we would expect the atomic_set() from CPU1 to either happen
111*4882a593Smuzhiyunbefore the atomic_add_unless(), in which case that latter one would no-op, or
112*4882a593Smuzhiyun_after_ in which case we'd overwrite its result. In no case is "2" a valid
113*4882a593Smuzhiyunoutcome.
114*4882a593Smuzhiyun
115*4882a593SmuzhiyunThis is typically true on 'normal' platforms, where a regular competing STORE
116*4882a593Smuzhiyunwill invalidate a LL/SC or fail a CMPXCHG.
117*4882a593Smuzhiyun
118*4882a593SmuzhiyunThe obvious case where this is not so is when we need to implement atomic ops
119*4882a593Smuzhiyunwith a lock:
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun  CPU0						CPU1
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun  atomic_add_unless(v, 1, 0);
124*4882a593Smuzhiyun    lock();
125*4882a593Smuzhiyun    ret = READ_ONCE(v->counter); // == 1
126*4882a593Smuzhiyun						atomic_set(v, 0);
127*4882a593Smuzhiyun    if (ret != u)				  WRITE_ONCE(v->counter, 0);
128*4882a593Smuzhiyun      WRITE_ONCE(v->counter, ret + 1);
129*4882a593Smuzhiyun    unlock();
130*4882a593Smuzhiyun
131*4882a593Smuzhiyunthe typical solution is to then implement atomic_set{}() with atomic_xchg().
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun
134*4882a593SmuzhiyunRMW ops:
135*4882a593Smuzhiyun
136*4882a593SmuzhiyunThese come in various forms:
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun - plain operations without return value: atomic_{}()
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun - operations which return the modified value: atomic_{}_return()
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun   these are limited to the arithmetic operations because those are
143*4882a593Smuzhiyun   reversible. Bitops are irreversible and therefore the modified value
144*4882a593Smuzhiyun   is of dubious utility.
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun - operations which return the original value: atomic_fetch_{}()
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun - swap operations: xchg(), cmpxchg() and try_cmpxchg()
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun - misc; the special purpose operations that are commonly used and would,
151*4882a593Smuzhiyun   given the interface, normally be implemented using (try_)cmpxchg loops but
152*4882a593Smuzhiyun   are time critical and can, (typically) on LL/SC architectures, be more
153*4882a593Smuzhiyun   efficiently implemented.
154*4882a593Smuzhiyun
155*4882a593SmuzhiyunAll these operations are SMP atomic; that is, the operations (for a single
156*4882a593Smuzhiyunatomic variable) can be fully ordered and no intermediate state is lost or
157*4882a593Smuzhiyunvisible.
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun
160*4882a593SmuzhiyunORDERING  (go read memory-barriers.txt first)
161*4882a593Smuzhiyun--------
162*4882a593Smuzhiyun
163*4882a593SmuzhiyunThe rule of thumb:
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun - non-RMW operations are unordered;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun - RMW operations that have no return value are unordered;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun - RMW operations that have a return value are fully ordered;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun - RMW operations that are conditional are unordered on FAILURE,
172*4882a593Smuzhiyun   otherwise the above rules apply.
173*4882a593Smuzhiyun
174*4882a593SmuzhiyunExcept of course when an operation has an explicit ordering like:
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun {}_relaxed: unordered
177*4882a593Smuzhiyun {}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE
178*4882a593Smuzhiyun {}_release: the W of the RMW (or atomic_set)  is a  RELEASE
179*4882a593Smuzhiyun
180*4882a593SmuzhiyunWhere 'unordered' is against other memory locations. Address dependencies are
181*4882a593Smuzhiyunnot defeated.
182*4882a593Smuzhiyun
183*4882a593SmuzhiyunFully ordered primitives are ordered against everything prior and everything
184*4882a593Smuzhiyunsubsequent. Therefore a fully ordered primitive is like having an smp_mb()
185*4882a593Smuzhiyunbefore and an smp_mb() after the primitive.
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun
188*4882a593SmuzhiyunThe barriers:
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun  smp_mb__{before,after}_atomic()
191*4882a593Smuzhiyun
192*4882a593Smuzhiyunonly apply to the RMW atomic ops and can be used to augment/upgrade the
193*4882a593Smuzhiyunordering inherent to the op. These barriers act almost like a full smp_mb():
194*4882a593Smuzhiyunsmp_mb__before_atomic() orders all earlier accesses against the RMW op
195*4882a593Smuzhiyunitself and all accesses following it, and smp_mb__after_atomic() orders all
196*4882a593Smuzhiyunlater accesses against the RMW op and all accesses preceding it. However,
197*4882a593Smuzhiyunaccesses between the smp_mb__{before,after}_atomic() and the RMW op are not
198*4882a593Smuzhiyunordered, so it is advisable to place the barrier right next to the RMW atomic
199*4882a593Smuzhiyunop whenever possible.
200*4882a593Smuzhiyun
201*4882a593SmuzhiyunThese helper barriers exist because architectures have varying implicit
202*4882a593Smuzhiyunordering on their SMP atomic primitives. For example our TSO architectures
203*4882a593Smuzhiyunprovide full ordered atomics and these barriers are no-ops.
204*4882a593Smuzhiyun
205*4882a593SmuzhiyunNOTE: when the atomic RmW ops are fully ordered, they should also imply a
206*4882a593Smuzhiyuncompiler barrier.
207*4882a593Smuzhiyun
208*4882a593SmuzhiyunThus:
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun  atomic_fetch_add();
211*4882a593Smuzhiyun
212*4882a593Smuzhiyunis equivalent to:
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun  smp_mb__before_atomic();
215*4882a593Smuzhiyun  atomic_fetch_add_relaxed();
216*4882a593Smuzhiyun  smp_mb__after_atomic();
217*4882a593Smuzhiyun
218*4882a593SmuzhiyunHowever the atomic_fetch_add() might be implemented more efficiently.
219*4882a593Smuzhiyun
220*4882a593SmuzhiyunFurther, while something like:
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun  smp_mb__before_atomic();
223*4882a593Smuzhiyun  atomic_dec(&X);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyunis a 'typical' RELEASE pattern, the barrier is strictly stronger than
226*4882a593Smuzhiyuna RELEASE because it orders preceding instructions against both the read
227*4882a593Smuzhiyunand write parts of the atomic_dec(), and against all following instructions
228*4882a593Smuzhiyunas well. Similarly, something like:
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun  atomic_inc(&X);
231*4882a593Smuzhiyun  smp_mb__after_atomic();
232*4882a593Smuzhiyun
233*4882a593Smuzhiyunis an ACQUIRE pattern (though very much not typical), but again the barrier is
234*4882a593Smuzhiyunstrictly stronger than ACQUIRE. As illustrated:
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun  C Atomic-RMW+mb__after_atomic-is-stronger-than-acquire
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun  {
239*4882a593Smuzhiyun  }
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun  P0(int *x, atomic_t *y)
242*4882a593Smuzhiyun  {
243*4882a593Smuzhiyun    r0 = READ_ONCE(*x);
244*4882a593Smuzhiyun    smp_rmb();
245*4882a593Smuzhiyun    r1 = atomic_read(y);
246*4882a593Smuzhiyun  }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun  P1(int *x, atomic_t *y)
249*4882a593Smuzhiyun  {
250*4882a593Smuzhiyun    atomic_inc(y);
251*4882a593Smuzhiyun    smp_mb__after_atomic();
252*4882a593Smuzhiyun    WRITE_ONCE(*x, 1);
253*4882a593Smuzhiyun  }
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun  exists
256*4882a593Smuzhiyun  (0:r0=1 /\ 0:r1=0)
257*4882a593Smuzhiyun
258*4882a593SmuzhiyunThis should not happen; but a hypothetical atomic_inc_acquire() --
259*4882a593Smuzhiyun(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome,
260*4882a593Smuzhiyunbecause it would not order the W part of the RMW against the following
261*4882a593SmuzhiyunWRITE_ONCE.  Thus:
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun  P0			P1
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun			t = LL.acq *y (0)
266*4882a593Smuzhiyun			t++;
267*4882a593Smuzhiyun			*x = 1;
268*4882a593Smuzhiyun  r0 = *x (1)
269*4882a593Smuzhiyun  RMB
270*4882a593Smuzhiyun  r1 = *y (0)
271*4882a593Smuzhiyun			SC *y, t;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyunis allowed.
274