synchronize_rcu()
Hold Off Readers?RCU callbacks are registered via call_rcu()
.
After an RCU grace period elapses, the callback (which is a C-language
function) is invoked.
RCU's fundamental guarantee states that once an RCU grace period has
elapsed, all RCU read-side critical sections that were executing when
the grace period began will have completed.
(An RCU read-side critical section is a fragment of code enclosed by
rcu_read_lock()
and rcu_read_unlock()
.)
Now, an RCU callback, being a C-language function, has a definite beginning
and end.
But what about synchronize_rcu()
, which blocks until an
RCU read-side critical section has elapsed?
How does RCU know how long to hold off new RCU read-side critical sections
once synchronize_rcu()
returns?
Of course, this is a completely abominable trick question.
The fact is that RCU never holds off new RCU read-side critical
sections under any circumstances.
This means that new RCU read-side critical sections might start before,
during, and after synchronize_rcu()
's invocation.
And they can just as easily start before, during, and after invocation
of an RCU callback!
Again, RCU's fundamental guarantee is only that any RCU read-side critical section that started before the beginning of a given grace period will have completed before the end of that grace period. This weak-seeming guarantee is surprisingly powerful. For example, imagine an RCU-protected data structure. Keep in mind that “RCU-protected” means that all read-side traversals of the data structure in question are wholly enclosed within RCU read-side critical sections. This permits you to safely delete an element from that data structure by first unlinking the element from the structure (so that subsequent readers cannot gain a reference to that element), then waiting for a grace period to elapse, and finally freeing the element, safe in the knowledge that there can no longer be any readers accessing it.
More information on RCU can be found
here
and in Documentation/RCU
in your friendly local
Linux source tree.