How Long Does 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.