Project

General

Profile

Actions

Feature #2785

open

113: Do not allow enabling interrupts while in an interrupt handler

Added by Alexey Khoroshilov over 12 years ago. Updated almost 12 years ago.

Status:
New
Priority:
Normal
Assignee:
Start date:
04/25/2012
Due date:
% Done:

0%

Estimated time:
Published in build:

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

Actions #1

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

Actions #2

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);

Actions #3

Updated by Vadim Mutilin over 12 years ago

  • Assignee set to Denis Efremov
Actions #5

Updated by Vadim Mutilin about 12 years ago

commits from linux-stable repository (with class specific:context:interrupt:enable_irq)
3e3742b
c690d5d

Actions #6

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.

Actions

Also available in: Atom PDF