Day 88 - Kernel Locking Internals¶
Date¶
2026-06-30
Today's Goal¶
Understand why the Linux kernel requires locking primitives to protect shared data, how race conditions occur, and when to use different synchronization mechanisms such as spinlocks, mutexes, and reader-writer semaphores.
Implement a simplified Linux-style locking framework and integrate it with the existing IRQ subsystem to demonstrate interrupt-safe synchronization using spin_lock_irqsave().
What I Learned¶
Why Kernel Locking¶
- Shared data accessed concurrently can lead to race conditions.
- A critical section must be protected to guarantee data consistency.
- Different execution contexts require different locking mechanisms.
Execution Context¶
- Process Context may sleep and use blocking synchronization.
- IRQ Context cannot sleep and must use atomic synchronization.
- Local IRQs can interrupt Process Context on the same CPU.
Spinlock¶
- Implemented a simplified Linux-style spinlock using C11 atomic compare-and-exchange.
- Learned that spinlocks protect short critical sections through busy waiting.
- Measured lock contention by counting retry attempts during lock acquisition.
- Understood why spinlocks must never sleep while holding the lock.
Mutex¶
- Implemented a simplified Linux-style mutex wrapper using POSIX pthread mutexes.
- Compared mutexes with spinlocks.
- Learned that mutexes suspend waiting threads instead of busy waiting.
spin_lock_irqsave()¶
- Simulated local IRQ enable/disable state.
- Implemented
spin_lock_irqsave()andspin_unlock_irqrestore(). - Demonstrated how disabling local IRQs prevents self-deadlock when an interrupt occurs while holding a spinlock.
Reader-Writer Synchronization¶
- Reviewed the purpose of Linux
rw_semaphore. - Compared
rw_semaphore,mutex, and RCU. - Understood that reader-writer locks allow multiple concurrent readers while writers remain exclusive.
IRQ Framework Refactoring¶
- Refactored the generic IRQ framework into an independent
utils/irqsubsystem. - Separated generic interrupt handling from the GPIO simulation framework.
- Improved the subsystem organization to better match the Linux kernel architecture.
Labs Completed¶
Lab 1 - Race Condition¶
Implemented a shared counter without synchronization and demonstrated race conditions caused by concurrent updates.
Lab 2 - Spinlock¶
Implemented a simplified Linux-style spinlock.
Verified:
- Atomic lock acquisition
- Busy waiting
- Lock contention
- Retry count statistics
Lab 3 - Mutex¶
Implemented a simplified Linux-style mutex.
Compared mutex behavior with spinlocks and verified correct protection of shared data.
Lab 4 - spin_lock_irqsave()¶
Integrated the locking framework with the IRQ subsystem.
Demonstrated:
- Process Context holding a spinlock
- IRQ arriving during the critical section
- Self-deadlock risk without
spin_lock_irqsave() - Deferred interrupt handling using
spin_lock_irqsave()andspin_unlock_irqrestore()
Key Takeaways¶
- Race conditions occur whenever multiple execution contexts modify shared data without synchronization.
- Spinlocks are suitable for atomic contexts such as IRQ handlers.
- Mutexes are suitable for sleepable contexts such as Process Context.
spin_lock_irqsave()protects against local IRQ re-entry while holding a spinlock.- Choosing the correct locking primitive depends on the execution context rather than the data itself.
rw_semaphoreis appropriate for read-heavy workloads where multiple readers may access shared data concurrently.
Next Step¶
Day 89 - Linux Kernel Memory Allocation
Topics:
- Physical vs Virtual Memory
- Kernel Address Space
- kmalloc()
- kzalloc()
- kcalloc()
- kfree()
- GFP Flags
- vmalloc()
- Memory Allocation Guidelines