Skip to content

Synchronization, RCU, Locking, And Atomics

Imported from _research/manual-study-linux/sync-rcu-locking.md.

Synchronization, RCU, Locking, And Atomics

Status: implemented source-backed volume.

Source Surface

  • kernel/rcu/tree.c: tree RCU state, grace-period management, callbacks.
  • include/linux/rcupdate.h: public RCU API and read-side lock/unlock behavior.
  • Documentation/memory-barriers.txt: memory-ordering model and READ_ONCE/WRITE_ONCE guidance.

Entry Points

RCU exposes a small public shape with deep implementation behind it: call_rcu(), synchronize_rcu(), and related helpers are declared in include/linux/rcupdate.h around lines 50-54. rcu_read_lock() and rcu_read_unlock() become preemption control in non-preempt RCU builds: the inline helpers around lines 101-110 call preempt_disable() and preempt_enable().

kernel/rcu/tree.c is the scalable implementation. It defines per-CPU rcu_data at line 80 and global rcu_state at line 92. The comments at lines 130-151 explain that RCU changes behavior across boot phases: before the scheduler is active it can use simple assumptions, then it transitions into full grace-period tracking.

Core Data Model

RCU separates readers, updaters, and reclamation:

  • Readers mark read-side critical sections and run cheaply.
  • Updaters publish a new version.
  • Reclamation waits for a grace period before freeing the old version.

The implementation uses per-CPU data and a combining tree to avoid one global hot lock. That is the reason this file is tree.c: scalable grace-period tracking is represented as a hierarchy.

Concurrency Contract

RCU is not a general lock. It protects pointer lifetime under a specific contract:

  1. Readers can traverse stable snapshots.
  2. Updaters must publish changes with correct ordering.
  3. Freed memory must wait until all pre-existing readers are gone.

Documentation/memory-barriers.txt is part of this subsystem because RCU only works when pointer publication and dependent loads obey memory-ordering rules. The document calls out READ_ONCE/WRITE_ONCE and the difference between compiler ordering, CPU ordering, acquire/release, and full barriers.

Rust Translation

Rust can encode part, but not all, of RCU:

  • RcuReadGuard should represent a read-side critical section.
  • RcuPtr<T> or RcuArc<T> should expose read access only under the guard.
  • Reclamation should be deferred by type, not by raw callback convention.
  • Unsafe code remains necessary at the publication/reclamation boundary.

The main trap is pretending normal Rust borrowing is enough. RCU allows concurrent readers and replacement, so a Rust API must model grace periods as a runtime lifetime domain.

AI-Native Translation

RCU maps cleanly to agent context snapshots. Agents can read immutable snapshots while a controller publishes new state. Old state is reclaimed only after no agent still holds a read epoch. This avoids stopping every agent for global configuration updates.

  • file-notes/linux__kernel__rcu__tree.c.md