Las interrupciones hardware usualmente se comunican con un bottom half, tasklet o softirq. Frecuentemente esto complica el poner el trabajo en una cola, que el BH/softirq debería de sacar.
Si un manejador irq hardware comparte datos con una softirq, tienes dos problemas. Primeramente, la softirq procesando puede ser interrumpida por una interrupción hardware, y segundo, la región crítica podría ser entrada por una interrupción hardware en otra CPU. Aquí es donde se usa spin_lock_irq(). Está definida para deshabilitar las interrupciones en esa cpu, entonces coge el bloqueo. spin_unlock_irq() hace lo inverso.
Esto también trabaja perfectamente para UP: el spinlock se desvanece, y esta macro simplemente se convierte en local_irq_disable() (include/asm/smp.h), qye te protege de que las softirq/tasklet/BH se ejecuten.
spin_lock_irqsave() (include/linux/spinlock.h) es una variante que salva cuando las interrupciones estaban habilidatas o deshabilitadas en una palabra de flags, que es pasada a spin_lock_irqrestore(). Esto significa que el mismo código puede ser usado dentro de un manejador irq hardware (donde las interrupciones ya estan deshabilitadas) y en softirqs (donde se requiere el deshabilitar las irqs).