Goal
Protection of a shared resource (often a data structure) from concurrent access
Primitive & Alternative
// Global,statically defined/initialized at compile time
static DEFINE_SPINLOCK(xxx_lock);
// Usage
unsigned long flags;
spin_lock_isrqsave(&xxx_lock, flags);
/* critical section */
spin_unlock_irqrestore(&xxx_lock, flags);
spinlock_t xxx_lock;
// __init, dynamically initialized at runtime
spin_lock_init(&xxx_lock);
// Usage
unsigned long flags;
spin_lock_irqsave(&xxx_lock, flags);
/* critical section */
spin_unlock_irqrestore(&xxx_lock, flags);
Reader-Writer
For a shared resource in which the resource is mostly read from, a read-writer
lock can be useful since multiple readers can be in the same critical region
at the same time.
rwlock_t xxx_lock = __RW_LOCK_UNLOCKED(xxx_lock);
// Usage
unsigned long flags;
read_lock_irqsave(&xxx_lock, flags);
/* critical section that only reads the info */
read_unlock_irqrestore(&xxx_lock, flags);
write_lock_irqsave(&xxx_lock, flags);
/* read and write exclusive access to the info */
write_unlock_irqrestore(&xxx_lock, flags);
Note:
reader-writer locks require more atomic operations than simple spinlocks
so only use if the reader critical section is long
Useful for complex data structures like linked lists, where you need to search for an entry without changing the lock itself
Non-Interrupt Handler Spinlocks
IFF you know that the spinlocks are never used in interrupt handlers, you can use the non-irq versions
spin_lock(&lock)
/* critical section */
spin_unlock(&lock)