Although RCU offers significant performance advantages for read-mostly workloads, one of the primary reasons for creating RCU in the first place was in fact its immunity to read-side deadlocks. This immunity stems from the fact that RCU read-side primitives do not block, spin, or even do backwards branches, so that their execution time is deterministic. It is therefore impossible for them to participate in a deadlock cycle.
Quick Quiz 10.14: Is there an exception to this deadlock immunity, and if so, what sequence of events could lead to deadlock? End Quick Quiz
An interesting consequence of RCU's read-side deadlock immunity is that it is possible to unconditionally upgrade an RCU reader to an RCU updater. Attempting to do such an upgrade with reader-writer locking results in deadlock. A sample code fragment that does an RCU read-to-update upgrade follows:
1 rcu_read_lock(); 2 list_for_each_entry_rcu(p, &head, list_field) { 3 do_something_with(p); 4 if (need_update(p)) { 5 spin_lock(my_lock); 6 do_update(p); 7 spin_unlock(&my_lock); 8 } 9 } 10 rcu_read_unlock(); |
Note that do_update() is executed under the protection of the lock and under RCU read-side protection.
Another interesting consequence of RCU's deadlock immunity is its immunity to a large class of priority inversion problems. For example, low-priority RCU readers cannot prevent a high-priority RCU updater from acquiring the update-side lock. Similarly, a low-priority RCU updater cannot prevent high-priority RCU readers from entering an RCU read-side critical section.
Paul E. McKenney 2011-12-16