Skip to content

Memory Barrier APIs

Purpose

Memory barriers define the ordering of memory accesses as observed by other CPUs and hardware devices.

Unlike synchronization primitives such as mutexes or spinlocks, memory barriers do not provide mutual exclusion. Instead, they prevent specific compiler or CPU memory reorderings.


#include <asm/barrier.h>
#include <linux/compiler.h>

Compiler Barrier

barrier()

Prevents the compiler from reordering memory accesses across the barrier.

barrier();

Typical usage:

shared_data = value;

barrier();

shared_flag = 1;

Full Memory Barrier

mb()

Prevents both loads and stores from being reordered across the barrier.

mb();

Typical usage:

shared_data = value;

mb();

shared_flag = 1;

Read Memory Barrier

rmb()

Prevents read operations from being reordered.

rmb();

Typical usage:

status = READ_ONCE(device->status);

rmb();

value = READ_ONCE(device->value);

Write Memory Barrier

wmb()

Prevents write operations from being reordered.

wmb();

Typical usage:

descriptor->addr = dma_addr;
descriptor->len = length;

wmb();

writel(1, doorbell);

SMP Memory Barriers

smp_mb()

Full memory barrier for CPU-to-CPU synchronization.

smp_mb();

smp_rmb()

Read memory barrier for SMP synchronization.

smp_rmb();

smp_wmb()

Write memory barrier for SMP synchronization.

smp_wmb();

Release Ordering

smp_store_release()

Stores a value while ensuring all previous memory accesses become visible first.

smp_store_release(ptr, value);

Typical usage:

shared_data = value;

smp_store_release(&ready, 1);

Acquire Ordering

smp_load_acquire()

Loads a value while ensuring subsequent memory accesses occur after the acquire operation.

value = smp_load_acquire(ptr);

Typical usage:

if (smp_load_acquire(&ready))
    consume(shared_data);

Ordering Summary

API Ordering Guarantee
barrier() Compiler ordering only
mb() Full CPU memory barrier
rmb() Read ordering
wmb() Write ordering
smp_mb() Full SMP memory barrier
smp_rmb() SMP read ordering
smp_wmb() SMP write ordering
smp_store_release() Release ordering
smp_load_acquire() Acquire ordering

Common Usage

Scenario Recommended API
Prevent compiler optimization barrier()
Publish shared data smp_store_release()
Consume published data smp_load_acquire()
Protect DMA descriptor publication wmb()
Synchronize CPUs smp_mb()
Order MMIO register writes wmb() or architecture-specific helpers

Notes

  • Compiler barriers only affect compiler optimizations.
  • CPU memory barriers control the visibility of memory accesses to other CPUs and devices.
  • Release/Acquire ordering is generally preferred over full memory barriers for producer-consumer synchronization because it provides the required ordering with less overhead.