@@ -19,8 +19,9 @@ Follow these rules to keep your RCU code working properly:
19
19
can reload the value, and won't your code have fun with two
20
20
different values for a single pointer! Without rcu_dereference(),
21
21
DEC Alpha can load a pointer, dereference that pointer, and
22
- return data preceding initialization that preceded the store of
23
- the pointer.
22
+ return data preceding initialization that preceded the store
23
+ of the pointer. (As noted later, in recent kernels READ_ONCE()
24
+ also prevents DEC Alpha from playing these tricks.)
24
25
25
26
In addition, the volatile cast in rcu_dereference() prevents the
26
27
compiler from deducing the resulting pointer value. Please see
@@ -34,7 +35,7 @@ Follow these rules to keep your RCU code working properly:
34
35
takes on the role of the lockless_dereference() primitive that
35
36
was removed in v4.15.
36
37
37
- - You are only permitted to use rcu_dereference on pointer values.
38
+ - You are only permitted to use rcu_dereference() on pointer values.
38
39
The compiler simply knows too much about integral values to
39
40
trust it to carry dependencies through integer operations.
40
41
There are a very few exceptions, namely that you can temporarily
@@ -240,6 +241,7 @@ precautions. To see this, consider the following code fragment::
240
241
struct foo *q;
241
242
int r1, r2;
242
243
244
+ rcu_read_lock();
243
245
p = rcu_dereference(gp2);
244
246
if (p == NULL)
245
247
return;
@@ -248,7 +250,10 @@ precautions. To see this, consider the following code fragment::
248
250
if (p == q) {
249
251
/* The compiler decides that q->c is same as p->c. */
250
252
r2 = p->c; /* Could get 44 on weakly order system. */
253
+ } else {
254
+ r2 = p->c - r1; /* Unconditional access to p->c. */
251
255
}
256
+ rcu_read_unlock();
252
257
do_something_with(r1, r2);
253
258
}
254
259
@@ -297,6 +302,7 @@ Then one approach is to use locking, for example, as follows::
297
302
struct foo *q;
298
303
int r1, r2;
299
304
305
+ rcu_read_lock();
300
306
p = rcu_dereference(gp2);
301
307
if (p == NULL)
302
308
return;
@@ -306,7 +312,12 @@ Then one approach is to use locking, for example, as follows::
306
312
if (p == q) {
307
313
/* The compiler decides that q->c is same as p->c. */
308
314
r2 = p->c; /* Locking guarantees r2 == 144. */
315
+ } else {
316
+ spin_lock(&q->lock);
317
+ r2 = q->c - r1;
318
+ spin_unlock(&q->lock);
309
319
}
320
+ rcu_read_unlock();
310
321
spin_unlock(&p->lock);
311
322
do_something_with(r1, r2);
312
323
}
@@ -364,7 +375,7 @@ the exact value of "p" even in the not-equals case. This allows the
364
375
compiler to make the return values independent of the load from "gp",
365
376
in turn destroying the ordering between this load and the loads of the
366
377
return values. This can result in "p->b" returning pre-initialization
367
- garbage values.
378
+ garbage values on weakly ordered systems .
368
379
369
380
In short, rcu_dereference() is *not * optional when you are going to
370
381
dereference the resulting pointer.
@@ -430,7 +441,7 @@ member of the rcu_dereference() to use in various situations:
430
441
SPARSE CHECKING OF RCU-PROTECTED POINTERS
431
442
-----------------------------------------
432
443
433
- The sparse static-analysis tool checks for direct access to RCU-protected
444
+ The sparse static-analysis tool checks for non-RCU access to RCU-protected
434
445
pointers, which can result in "interesting" bugs due to compiler
435
446
optimizations involving invented loads and perhaps also load tearing.
436
447
For example, suppose someone mistakenly does something like this::
0 commit comments