6.3 About Handling Access to Shared Resources

Multiple threads of execution can operate simultaneously on shared kernel data structures. As a result, you must ensure that such access is serialized. You can use spinlocks and mutexes to control access to critical sections, which are areas of code that contain shared resources.

It is better to use mutexes than spinlocks when the wait time is expected to be more than two context switches. However, inside an interrupt handler, you must always use a spinlock because a mutex can put a thread to sleep. Conversely, if the critical section needs to sleep, you must use a mutex as a thread must not be scheduled, preempted, or put to sleep after it has acquired a spinlock.

Note

The mutex interface was introduced as an alternative to the semaphore interface. Semaphores allow simultaneous access by a specified number of threads to a critical section, but this feature is almost never used.

When a thread can only either read from or write to a critical region, there are also the read_lock() and write_lock() functions that you can use to implement reader or writer spin locks. A writer spinlock blocks access to all other writing or reading threads. A reader spinlock blocks access to other writing threads but allows access from other reading threads.

As an alternative to spinlocks and mutexes, you can use the 32 and 64-bit atomic integer types (atomic_t and atomic64_t) and perform operations such as incrementing counters and setting bit masks.

Finally, if a single writer thread maintains a data structure that is always seen consistently by a reader thread, you can use a lock-less circular buffer such as the kfifo structure that is defined in <linux/kfifo.h>. Network drivers typically use such buffers to exchange data with the adapter.