Skip to content

Kernel Locking

Purpose

Kernel locking protects shared data accessed by multiple execution contexts.

Without proper synchronization, concurrent access may lead to race conditions, data corruption, or inconsistent system state.

Linux provides different locking primitives depending on whether the current execution context is allowed to sleep.


Why Locking Is Required

Consider two execution contexts modifying the same variable.

Process Context
    counter++

IRQ Context
    counter++

Without synchronization, the updates may overlap and produce incorrect results.

This situation is known as a race condition.


Critical Section

A critical section is a region of code that accesses shared data.

Only one execution context should modify the protected data at a time.

Typical examples include:

  • Shared queues
  • Device state
  • Configuration structures
  • Hardware registers

Execution Context

Linux locking primitives are selected based on the current execution context.

Context Can Sleep Typical Lock
Process Context Yes mutex
IRQ Context No spinlock
Threaded IRQ Yes mutex or spinlock
Workqueue Yes mutex or spinlock
Kernel Thread Yes mutex or spinlock

Spinlock

A spinlock provides mutual exclusion through busy waiting.

When the lock is unavailable, the caller repeatedly retries until the lock becomes available.

Characteristics:

  • Busy waiting
  • Cannot sleep
  • Suitable for short critical sections
  • Safe in IRQ context

Common APIs:

spin_lock(&lock);

...

spin_unlock(&lock);

For interrupt-safe locking:

spin_lock_irqsave(&lock, flags);

...

spin_unlock_irqrestore(&lock, flags);

Mutex

A mutex provides mutual exclusion by blocking the calling thread while waiting for the lock.

Characteristics:

  • Sleepable
  • Suitable for Process Context
  • Cannot be used inside interrupt handlers

Common APIs:

mutex_lock(&lock);

...

mutex_unlock(&lock);

Reader-Writer Semaphore

A reader-writer semaphore allows multiple readers to access shared data simultaneously while writers remain exclusive.

Characteristics:

  • Multiple concurrent readers
  • Single exclusive writer
  • Suitable for read-heavy workloads

Common APIs:

down_read(&rwsem);

...

up_read(&rwsem);
down_write(&rwsem);

...

up_write(&rwsem);

Lock Selection

Situation Recommended Lock
Shared data in Process Context mutex
Shared data accessed by IRQ handlers spinlock
Process Context + IRQ Context spin_lock_irqsave()
Read-heavy shared data rw_semaphore

Relationship with Other Kernel Components

Kernel locking works together with many kernel subsystems.

Typical relationships include:

IRQ
spinlock
Shared Queue
wake_up()

poll()

epoll()

SIGIO

Workqueues and kernel threads often process data protected by the same locking primitives after the interrupt handler completes.