Hardware interrupts usually communicate with a bottom half, tasklet or softirq. Frequently this involves putting work in a queue, which the BH/softirq will take out.
If a hardware irq handler shares data with a softirq, you have
two concerns. Firstly, the softirq processing can be
interrupted by a hardware interrupt, and secondly, the
critical region could be entered by a hardware interrupt on
another CPU. This is where spin_lock_irq()
is
used. It is defined to disable interrupts on that cpu, then grab
the lock. spin_unlock_irq()
does the reverse.
This works perfectly for UP as well: the spin lock vanishes,
and this macro simply becomes local_irq_disable()
(include/asm/smp.h), which
protects you from the softirq/tasklet/BH being run.
spin_lock_irqsave()
(include/linux/spinlock.h) is a variant
which saves whether interrupts were on or off in a flags word,
which is passed to spin_lock_irqrestore()
. This
means that the same code can be used inside an hard irq handler (where
interrupts are already off) and in softirqs (where the irq
disabling is required).