The RCU API tables
These tables are part of Paul McKenney's 2014 RCU API update article
RCU Per-Flavor API Table
Attribute | RCU | RCU BH | RCU Sched | SRCU | Generic |
---|---|---|---|---|---|
Purpose | Wait for RCU read-side critical sections | Wait for RCU-bh read-side critical sections & irqs | Wait for RCU-sched read-side critical sections, preempt-disable regions, hardirqs, & NMIs | Wait for SRCU read-side critical sections, allow sleeping readers | Primitives common to all flavors of RCU |
Initialization | N/A | N/A | N/A | DEFINE_SRCU() DEFINE_STATIC_SRCU() init_srcu_struct() |
RCU_INIT_POINTER() RCU_POINTER_INITIALIZER() |
Read-side critical-section markers |
rcu_read_lock() rcu_read_unlock() |
rcu_read_lock_bh() rcu_read_unlock_bh() |
rcu_read_lock_sched() rcu_read_unlock_sched() rcu_read_lock_sched_notrace() rcu_read_unlock_sched_notrace() preempt_disable() /preempt_enable() local_irq_save() /local_irq_restore() |
srcu_read_lock() srcu_read_unlock() |
|
Read-side data access |
rcu_dereference() rcu_dereference_check() |
rcu_dereference_bh() rcu_dereference_bh_check() |
rcu_dereference_sched() rcu_dereference_sched_check() |
srcu_dereference() srcu_dereference_check() |
rcu_access_index()
rcu_access_pointer() rcu_dereference_index_check() rcu_dereference_protected() rcu_dereference_raw() rcu_dereference_raw_notrace() |
Update-side primitives (synchronous) |
synchronize_rcu() synchronize_net() |
synchronize_rcu_bh() |
synchronize_sched() |
synchronize_srcu() |
rcu_assign_pointer() |
Update-side primitives (expedited) |
synchronize_rcu_expedited() |
synchronize_rcu_bh_expedited() |
synchronize_sched_expedited() |
synchronize_srcu_expedited() |
|
Update-side primitives (asynchronous/callback) |
call_rcu() |
call_rcu_bh() |
call_rcu_sched() |
call_srcu() |
|
Update-side primitives (wait for callbacks) |
rcu_barrier() |
rcu_barrier_bh() |
rcu_barrier_sched() |
srcu_barrier() |
|
Update-side primitives (free memory) |
kfree_rcu() |
||||
Validation | rcu_read_lock_held() |
rcu_read_lock_bh_held() |
rcu_read_lock_sched_held() |
srcu_read_lock_held() |
__rcu init_rcu_head() destroy_rcu_head() init_rcu_head_on_stack() destroy_rcu_head_on_stack() rcu_is_watching() rcu_lockdep_assert() RCU_NONIDLE() |
Memory ordering | smp_mb__after_srcu_read_unlock() |
||||
Read side constraints | No blocking except preemption and “spinlock” acquisition. | No BH enabling | No blocking | No wait for synchronize_srcu() |
|
Read side overhead | Simple instructions (free on !PREEMPT) | BH disable/enable | Preempt disable/enable (free on !PREEMPT) | Simple instructions, preempt disable/enable | |
Asynchronous update-side overhead
(for example, call_rcu() ) |
sub-microsecond | sub-microsecond | sub-microsecond | sub-microsecond | |
Grace-period latency | 10s of milliseconds | 10s of milliseconds | 10s of milliseconds | 10s of microseconds, but increases with number of CPUs (rough rule of thumb: 200 nanoseconds per CPU) | |
!PREEMPT_RT default implementation | RCU Sched | RCU BH | RCU Sched | SRCU | |
PREEMPT_RT default implementation | Preemptible RCU | RCU BH | RCU Sched | SRCU |
RCU List APIs
Operation | list | hlist | hlist_nulls | hlist_bl |
---|---|---|---|---|
Circular doubly linked list | Linear doubly linked list | Linear doubly linked list with marked NULL pointer, with up to 31 bits of marking |
Linear doubly linked list with bit locking | |
Initialization | INIT_LIST_HEAD_RCU() |
|||
Full traversal | list_for_each_entry_rcu() |
hlist_for_each_entry_rcu() hlist_for_each_entry_rcu_bh() hlist_for_each_entry_rcu_notrace() |
hlist_nulls_for_each_entry_rcu() |
hlist_bl_for_each_entry_rcu() |
Resume traversal | list_for_each_entry_continue_rcu() |
hlist_for_each_entry_continue_rcu() hlist_for_each_entry_continue_rcu_bh() |
||
Stepwise traversal | list_entry_rcu() list_first_or_null_rcu() list_next_rcu() |
hlist_first_rcu() hlist_next_rcu() hlist_pprev_rcu() |
hlist_nulls_first_rcu() hlist_nulls_next_rcu() |
hlist_bl_first_rcu() |
Add | list_add_rcu() list_add_tail_rcu() |
hlist_add_after_rcu() hlist_add_before_rcu() hlist_add_head_rcu() |
hlist_nulls_add_head_rcu() |
hlist_bl_add_head_rcu() hlist_bl_set_first_rcu() |
Delete | list_del_rcu() |
hlist_del_rcu() hlist_del_init_rcu() |
hlist_nulls_del_rcu() hlist_nulls_del_init_rcu() |
hlist_bl_del_rcu() hlist_bl_del_init_rcu() |
Replacement | list_replace_rcu() |
hlist_replace_rcu() |
||
Splice | list_splice_init_rcu() |