···1919 can reload the value, and won't your code have fun with two2020 different values for a single pointer! Without rcu_dereference(),2121 DEC Alpha can load a pointer, dereference that pointer, and2222- return data preceding initialization that preceded the store of2323- the pointer.2222+ return data preceding initialization that preceded the store2323+ of the pointer. (As noted later, in recent kernels READ_ONCE()2424+ also prevents DEC Alpha from playing these tricks.)24252526 In addition, the volatile cast in rcu_dereference() prevents the2627 compiler from deducing the resulting pointer value. Please see···3534 takes on the role of the lockless_dereference() primitive that3635 was removed in v4.15.37363838-- You are only permitted to use rcu_dereference on pointer values.3737+- You are only permitted to use rcu_dereference() on pointer values.3938 The compiler simply knows too much about integral values to4039 trust it to carry dependencies through integer operations.4140 There are a very few exceptions, namely that you can temporarily···241240 struct foo *q;242241 int r1, r2;243242243243+ rcu_read_lock();244244 p = rcu_dereference(gp2);245245 if (p == NULL)246246 return;···250248 if (p == q) {251249 /* The compiler decides that q->c is same as p->c. */252250 r2 = p->c; /* Could get 44 on weakly order system. */251251+ } else {252252+ r2 = p->c - r1; /* Unconditional access to p->c. */253253 }254254+ rcu_read_unlock();254255 do_something_with(r1, r2);255256 }256257···302297 struct foo *q;303298 int r1, r2;304299300300+ rcu_read_lock();305301 p = rcu_dereference(gp2);306302 if (p == NULL)307303 return;···312306 if (p == q) {313307 /* The compiler decides that q->c is same as p->c. */314308 r2 = p->c; /* Locking guarantees r2 == 144. */309309+ } else {310310+ spin_lock(&q->lock);311311+ r2 = q->c - r1;312312+ spin_unlock(&q->lock);315313 }314314+ rcu_read_unlock();316315 spin_unlock(&p->lock);317316 do_something_with(r1, r2);318317 }···375364compiler to make the return values independent of the load from "gp",376365in turn destroying the ordering between this load and the loads of the377366return values. This can result in "p->b" returning pre-initialization378378-garbage values.367367+garbage values on weakly ordered systems.379368380369In short, rcu_dereference() is *not* optional when you are going to381370dereference the resulting pointer.···441430SPARSE CHECKING OF RCU-PROTECTED POINTERS442431-----------------------------------------443432444444-The sparse static-analysis tool checks for direct access to RCU-protected433433+The sparse static-analysis tool checks for non-RCU access to RCU-protected445434pointers, which can result in "interesting" bugs due to compiler446435optimizations involving invented loads and perhaps also load tearing.447436For example, suppose someone mistakenly does something like this::