Re: [DOCUMENTATION] Revised Unreliable Kernel Locking Guide
From: Manfred Spraul
Date: Fri Dec 12 2003 - 22:18:41 EST
Hi Rusty,
From Chapter 4.1:
|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_unlock_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).
Interrupts are typically on within the hard irq handler.
spin_lock() is usually ok because an interrupt handler is never
reentered. Thus if a lock is only accessed from a single irq handler,
then spin_lock() is the faster approach. That's why many nic drivers use
spin_lock instead of spin_lock_irqsave() in their irq handlers.
OTHO: if a driver lock is a global resource that is used from different
irqs, then it must either use _irqsave(), or set SA_INTERRUPT.
Examples: rtc_lock relies on SA_INTERRUPT: it's touched from the rtc irq
and the timer irq path, and both rtc and timer set SA_INTERRUPT.
I assume ide relies on _irqsave(), but the code is too difficult to follow.
Btw, perhaps you could add the 2nd synchronization approach for
interrupts: if it's an extremely rare event, then no lock at all in the
irq handler (no reentrancy guaranteed by the kernel), and
spin_lock+disable_irq() in the softirq/tasklet. My network drivers use
that to synchronize packet rx with close.
--
Manfred
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/