Skip to content

Commit

Permalink
[PATCH] genirq: do not mask interrupts by default
Browse files Browse the repository at this point in the history
Never mask interrupts immediately upon request.  Disabling interrupts in
high-performance codepaths is rare, and on the other hand this change could
recover lost edges (or even other types of lost interrupts) by conservatively
only masking interrupts after they happen.  (NOTE: with this change the
highlevel irq-disable code still soft-disables this IRQ line - and if such an
interrupt happens then the IRQ flow handler keeps the IRQ masked.)

Mark i8529A controllers as 'never loses an edge'.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ingo Molnar authored and Linus Torvalds committed Feb 16, 2007
1 parent 1f2ea08 commit 76d2160
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 7 deletions.
1 change: 1 addition & 0 deletions arch/i386/kernel/i8259.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static void mask_and_ack_8259A(unsigned int);
static struct irq_chip i8259A_chip = {
.name = "XT-PIC",
.mask = disable_8259A_irq,
.disable = disable_8259A_irq,
.unmask = enable_8259A_irq,
.mask_ack = mask_and_ack_8259A,
};
Expand Down
1 change: 1 addition & 0 deletions arch/x86_64/kernel/i8259.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static void mask_and_ack_8259A(unsigned int);
static struct irq_chip i8259A_chip = {
.name = "XT-PIC",
.mask = disable_8259A_irq,
.disable = disable_8259A_irq,
.unmask = enable_8259A_irq,
.mask_ack = mask_and_ack_8259A,
};
Expand Down
17 changes: 10 additions & 7 deletions kernel/irq/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,6 @@ static void default_enable(unsigned int irq)
*/
static void default_disable(unsigned int irq)
{
struct irq_desc *desc = irq_desc + irq;

if (!(desc->status & IRQ_DELAYED_DISABLE))
desc->chip->mask(irq);
}

/*
Expand Down Expand Up @@ -298,13 +294,18 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)

if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
kstat_cpu(cpu).irqs[irq]++;

action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
if (desc->chip->mask)
desc->chip->mask(irq);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
desc->status |= IRQ_PENDING;
goto out_unlock;
}

desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING);
desc->status |= IRQ_INPROGRESS;
spin_unlock(&desc->lock);

Expand Down Expand Up @@ -396,11 +397,13 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)

/*
* If its disabled or no action available
* keep it masked and get out of here
* then mask it and get out of here:
*/
action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
desc->status |= IRQ_PENDING;
if (desc->chip->mask)
desc->chip->mask(irq);
goto out;
}

Expand Down

0 comments on commit 76d2160

Please sign in to comment.