Reputation: 5211
I'm maintaining a driver which shares some resource between the ISR (i.e., in interrupt context) and the read()
syscall. In both cases, spin_lock_irqsave()
is used, since (obviously) the resource can be acquired in the interrupt context.
However, I was wondering if using spin_lock_irqsave()
is necessary in the interrupt context. Namely, the Unreliable Guide to Locking (see here: https://kernel.readthedocs.io/en/sphinx-samples/kernel-locking.html) states:
Note that the
spin_lock_irqsave()
will turn off interrupts if they are on, otherwise does nothing (if we are already in an interrupt handler), hence these functions are safe to call from any context.
As a result, is it common practice to use "normal" spin_lock()
in the interrupt handler (since the particular interrupt is already disabled) and then call spin_lock_irqsave()
in the user context? Alternatively, is the better practice to just use spin_lock_irqsave()
everywhere? I'm leaning towards the latter, for two reasons:
spin_lock_irqsave()
, it's obvious that the lock is intended to be shared with the interrupt context.spin_lock_irqsave()
works in any context, so you don't have to ensure that a function is only called in a certain context.With the above said, I'm wondering what the convention/best practice is for code that resides in kernel space. Is it better to use spin_lock_irqsave()
everywhere the lock is acquired, even if you can guarantee that the lock is being acquired from the interrupt context?
Upvotes: 4
Views: 3604
Reputation: 21
See Unreliable Guide To Locking in kernel documentation. There's a table of minimum requirements for locking to synchronize between different contexts which, roughly speaking, can be summarized as:
spin_lock_bh
, which disables softirq while locking.spin_lock_irq
or spin_lock_irqsave
, depending on whether the other is hard irq or not.spin_lock
.(Of course, those are under assumption that your kernel isn't config as PREEMPT_RT
)
Upvotes: 1