RCU API Usage¶
Overview¶
Read-Copy-Update (RCU) is a synchronization mechanism optimized for read-mostly workloads.
Unlike mutexes and rwlocks, RCU focuses on:
- Object publication
- Reader-side protection
- Grace period detection
- Deferred reclamation
RCU does not provide mutual exclusion.
Instead, it allows readers to access shared objects without blocking while writers publish new versions and reclaim old versions after a grace period.
Core Concepts¶
RCU separates object lifetime management into three phases:
A writer may publish a new object immediately, but reclamation of the old object must be deferred until all readers that could still reference it have exited their read-side critical sections.
RCU Read-Side APIs¶
rcu_read_lock()¶
Marks the beginning of an RCU read-side critical section.
Conceptually:
rcu_read_unlock()¶
Marks the end of an RCU read-side critical section.
Conceptually:
Pointer Access APIs¶
rcu_dereference()¶
Safely loads an RCU-protected pointer.
Conceptually:
Provides acquire semantics.
This guarantees that once a reader observes the published pointer, it also observes the object initialization performed before publication.
Why Not Use a Normal Pointer Load?¶
Using:
does not provide the required ordering guarantees.
Without acquire semantics, a reader could observe:
which may result in partially initialized data being accessed.
Pointer Publication APIs¶
rcu_assign_pointer()¶
Safely publishes an RCU-protected pointer.
Conceptually:
Provides release semantics.
This guarantees:
and prevents publication from occurring before initialization.
Why Not Use a Normal Pointer Store?¶
Using:
does not guarantee ordering.
Compiler or CPU reordering could allow readers to observe a pointer before all object fields are fully initialized.
Grace Period APIs¶
synchronize_rcu()¶
Waits until all current readers have exited their read-side critical sections.
Conceptually:
This is a blocking operation.
The caller cannot continue until the grace period completes.
Deferred Reclamation APIs¶
call_rcu()¶
Schedules a callback to execute after a grace period.
Conceptually:
Unlike synchronize_rcu(), this does not block the caller.
struct rcu_head¶
RCU uses callback descriptors to track deferred reclamation requests.
Typically embedded inside reclaimable objects:
This allows the callback to recover the containing object and perform cleanup.
Publication vs Reclamation¶
One of the most important RCU principles is:
Publishing a new object:
does not mean the old object can be reclaimed immediately.
Readers that entered before publication may still hold references to the old object.
The old object must remain valid until the grace period completes.
synchronize_rcu() vs call_rcu()¶
| API | Behavior |
|---|---|
| synchronize_rcu() | Blocking reclamation |
| call_rcu() | Asynchronous reclamation |
Example:
versus:
Relationship to Mini RCU¶
A simplified educational implementation may look like:
with:
This is useful for understanding grace periods, but it is not how Linux RCU scales.
Linux RCU avoids global reader counters and instead relies on:
- Per-CPU state
- Quiescent state tracking
- Grace period detection mechanisms
These topics are part of RCU internals and are discussed separately.
Summary¶
RCU is a framework for safe object publication and reclamation.
The fundamental workflow is:
Reader
↓
rcu_read_lock()
rcu_dereference()
rcu_read_unlock()
Writer
↓
rcu_assign_pointer()
Reclaimer
↓
synchronize_rcu()
or
call_rcu()
This separation allows readers to execute with minimal overhead while writers safely replace and eventually reclaim old objects.