Concurrency in the Kernel
Multiple threads of execution need to be synchronized to avoid data corruption and even system freezes.
Tuesday, November 15th, 2005
As the Linux kernel has grown in complexity to support Symmetric Multi-Processing (SMP) and kernel preemption, more and more scenarios generate multiple threads of execution. Because threads can simultaneously operate on shared kernel data structures, access to such data structures has to be serialized. In this column, let’s learn the basics of protecting shared kernel resources from concurrent access, starting with a simple example and slowly introducing complexities like interrupts, kernel preemption, and SMP.
Spinlocks and Semaphores
A code area that accesses shared resources is called a critical section. Spinlocks and semaphores are the two mechanisms used to protect critical sections in the kernel.
A spinlock ensures that only a single thread enters a critical section at any time. Any other thread that wants to enter the critical section must wait “spinning its wheels” until the first thread exits. Listing One shows a basic use of a spinlock.
#include <linux/spinlock.h>
/* Initialize */
spinlock_t mylock = SPIN_LOCK_UNLOCKED;
/* Try to acquire the spinlock. This is inexpensive if there
* is no one inside the critical section. In the face of contention,
* spinlock() busy waits.
*/
spin_lock (&mylock);
/* … Critical Section … */
/* Release the lock */
spin_unlock (&mylock);
In contrast to spinlocks, which put threads into a spin if they attempt to enter a busy critical section, a semaphore puts each contending thread to sleep until its turn arrives to occupy the critical section.