Because grace periods are not allowed to complete while there is an RCU read-side critical section in progress, the RCU read-side primitives may be used as a restricted reference-counting mechanism. For example, consider the following code fragment:
1 rcu_read_lock(); /* acquire reference. */ 2 p = rcu_dereference(head); 3 /* do something with p. */ 4 rcu_read_unlock(); /* release reference. */ |
The rcu_read_lock() primitive can be thought of as acquiring a reference to p, because a grace period starting after the rcu_dereference() assigns to p cannot possibly end until after we reach the matching rcu_read_unlock(). This reference-counting scheme is restricted in that we are not allowed to block in RCU read-side critical sections, nor are we permitted to hand off an RCU read-side critical section from one task to another.
Regardless of these restrictions, the following code can safely delete p:
1 spin_lock(&mylock); 2 p = head; 3 rcu_assign_pointer(head, NULL); 4 spin_unlock(&mylock); 5 /* Wait for all references to be released. */ 6 synchronize_rcu(); 7 kfree(p); |
The assignment to head prevents any future references to p from being acquired, and the synchronize_rcu() waits for any previously acquired references to be released.
Quick Quiz 10.15: But wait! This is exactly the same code that might be used when thinking of RCU as a replacement for reader-writer locking! What gives? End Quick Quiz
Of course, RCU can also be combined with traditional reference counting,
as has been discussed on LKML and as summarized in
Section .
But why bother?
Again, part of the answer is performance, as shown in
Figure ,
again showing data taken on a 16-CPU 3GHz Intel x86 system.
Quick Quiz 10.16: Why the dip in refcnt overhead near 6 CPUs? End Quick Quiz
And, as with reader-writer locking, the performance advantages
of RCU are most pronounced for short-duration critical sections, as shown
Figure
for a 16-CPU system.
In addition, as with reader-writer locking, many system calls (and thus
any RCU read-side critical sections that they contain) complete in
a few microseconds.
However, the restrictions that go with RCU can be quite onerous. For example, in many cases, the prohibition against sleeping while in an RCU read-side critical section would defeat the entire purpose. The next section looks at ways of addressing this problem, while also reducing the complexity of traditional reference counting, at least in some cases.
Paul E. McKenney 2011-12-16