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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With