If a softirq shares
data with user context, you have two problems. Firstly, the current
user context can be interrupted by a softirq, and secondly, the
critical region could be entered from another CPU. This is where
spin_lock_bh()
(include/linux/spinlock.h) is
used. It disables softirqs on that CPU, then grabs the lock.
spin_unlock_bh()
does the reverse. (The
'_bh' suffix is a historical reference to "Bottom Halves", the
old name for software interrupts. It should really be
called spin_lock_softirq()' in a perfect world).
Note that you can also use spin_lock_irq()
or spin_lock_irqsave()
here, which stop
hardware interrupts as well: see Chapter 4.
This works perfectly for UP
as well: the spin lock vanishes, and this macro
simply becomes local_bh_disable()
(include/linux/interrupt.h), which
protects you from the softirq being run.