Skip to content

Commit b33994e

Browse files
committed
doc: Update rcu_dereference.rst
This commit updates rcu_dereference.rst to reflect RCU additions and changes over the past few years Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 42d689e commit b33994e

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

Documentation/RCU/rcu_dereference.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ Follow these rules to keep your RCU code working properly:
1919
can reload the value, and won't your code have fun with two
2020
different values for a single pointer! Without rcu_dereference(),
2121
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.)
2425

2526
In addition, the volatile cast in rcu_dereference() prevents the
2627
compiler from deducing the resulting pointer value. Please see
@@ -34,7 +35,7 @@ Follow these rules to keep your RCU code working properly:
3435
takes on the role of the lockless_dereference() primitive that
3536
was removed in v4.15.
3637

37-
- You are only permitted to use rcu_dereference on pointer values.
38+
- You are only permitted to use rcu_dereference() on pointer values.
3839
The compiler simply knows too much about integral values to
3940
trust it to carry dependencies through integer operations.
4041
There are a very few exceptions, namely that you can temporarily
@@ -240,6 +241,7 @@ precautions. To see this, consider the following code fragment::
240241
struct foo *q;
241242
int r1, r2;
242243

244+
rcu_read_lock();
243245
p = rcu_dereference(gp2);
244246
if (p == NULL)
245247
return;
@@ -248,7 +250,10 @@ precautions. To see this, consider the following code fragment::
248250
if (p == q) {
249251
/* The compiler decides that q->c is same as p->c. */
250252
r2 = p->c; /* Could get 44 on weakly order system. */
253+
} else {
254+
r2 = p->c - r1; /* Unconditional access to p->c. */
251255
}
256+
rcu_read_unlock();
252257
do_something_with(r1, r2);
253258
}
254259

@@ -297,6 +302,7 @@ Then one approach is to use locking, for example, as follows::
297302
struct foo *q;
298303
int r1, r2;
299304

305+
rcu_read_lock();
300306
p = rcu_dereference(gp2);
301307
if (p == NULL)
302308
return;
@@ -306,7 +312,12 @@ Then one approach is to use locking, for example, as follows::
306312
if (p == q) {
307313
/* The compiler decides that q->c is same as p->c. */
308314
r2 = p->c; /* Locking guarantees r2 == 144. */
315+
} else {
316+
spin_lock(&q->lock);
317+
r2 = q->c - r1;
318+
spin_unlock(&q->lock);
309319
}
320+
rcu_read_unlock();
310321
spin_unlock(&p->lock);
311322
do_something_with(r1, r2);
312323
}
@@ -364,7 +375,7 @@ the exact value of "p" even in the not-equals case. This allows the
364375
compiler to make the return values independent of the load from "gp",
365376
in turn destroying the ordering between this load and the loads of the
366377
return values. This can result in "p->b" returning pre-initialization
367-
garbage values.
378+
garbage values on weakly ordered systems.
368379

369380
In short, rcu_dereference() is *not* optional when you are going to
370381
dereference the resulting pointer.
@@ -430,7 +441,7 @@ member of the rcu_dereference() to use in various situations:
430441
SPARSE CHECKING OF RCU-PROTECTED POINTERS
431442
-----------------------------------------
432443

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
434445
pointers, which can result in "interesting" bugs due to compiler
435446
optimizations involving invented loads and perhaps also load tearing.
436447
For example, suppose someone mistakenly does something like this::

0 commit comments

Comments
 (0)