Feature #2785
open113: Do not allow enabling interrupts while in an interrupt handler
0%
Description
Can't allow enabling interrupts while in an interrupt handler, that's general bad form and such.
spin_unlock_irq() cannot be called in IRQ context
as well as
local_irq_enable()
rwlock:
read_unlock_irq()
write_unlock_irq()
seqlock:
write_sequnlock_irq()
on_each_cpu()
and may be others.
[specific:context:interrupt:enable_irq]
As an example of fix see:
PM / Runtime: Don't enable interrupts while running in_interrupt
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=commitdiff;h=c3810c88788d505d4ffd786addd111b745e42161
https://bugzilla.kernel.org/show_bug.cgi?id=27482
Updated by Alexey Khoroshilov over 12 years ago
The second example:
[SCSI] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=commitdiff;h=1e7de68c57daf75ec4b721f101f88cccf029e38c
Updated by Vadim Mutilin over 12 years ago
spin_unlock_irq() cannot be called in IRQ context
But the patch in the second example enables call to spin_unlock_irq
- spin_unlock(&dev->stats_lock); + spin_unlock_irq(&dev->stats_lock);
Updated by Vadim Mutilin about 12 years ago
commits from linux-stable repository (with class specific:context:interrupt:enable_irq)
3e3742b
c690d5d
Updated by Evgeny Novikov almost 12 years ago
After careful reading "The Spinlock Functions" section of 5th LDD3 chapter I guess that there is another problem actually. Being in interrupt context one should use spin locking that disables interrupts. Otherwise sooner or later the system may catch a deadlock. That is why Vadim has properly noticed that spin_[un]lock was changed with spin_[un]lock_irq in interrupt context:
Vadim Mutilin wrote:
[...]
But the patch in the second example enables call to spin_unlock_irq
[...]
The problem considered in description comes from sequence:
spin_unlock_irq(&a);
spin_lock_irqsave(&b);
spin_unlock_irqsave(&b);
spin_lock_irq(&a);
that may happen in interrupt context. I guess, that the reason is following. In interrupt context one unlock external spin lock by means of spin_unlock_irq. I.e. one both enable interrupts (that should be disabled as noted in comment) and unlock spin lock. This may lead to some other interrupt handler may happen and cause deadlock.
Another problem, e.g. as considered in example provided by Denis, is in spin_lock_irq vs spin_lock_irqsave usage. It's also considered in "The Spinlock Functions" section. Here you can find an example of bad things. BTW eventually spin_[un]lock_irq used in this commit was changed with spin_lock_irqsave/spin_unlock_irqrestore.