Commit 76d21601 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] genirq: do not mask interrupts by default

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: default avatarIngo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1f2ea083
...@@ -41,6 +41,7 @@ static void mask_and_ack_8259A(unsigned int); ...@@ -41,6 +41,7 @@ static void mask_and_ack_8259A(unsigned int);
static struct irq_chip i8259A_chip = { static struct irq_chip i8259A_chip = {
.name = "XT-PIC", .name = "XT-PIC",
.mask = disable_8259A_irq, .mask = disable_8259A_irq,
.disable = disable_8259A_irq,
.unmask = enable_8259A_irq, .unmask = enable_8259A_irq,
.mask_ack = mask_and_ack_8259A, .mask_ack = mask_and_ack_8259A,
}; };
......
...@@ -103,6 +103,7 @@ static void mask_and_ack_8259A(unsigned int); ...@@ -103,6 +103,7 @@ static void mask_and_ack_8259A(unsigned int);
static struct irq_chip i8259A_chip = { static struct irq_chip i8259A_chip = {
.name = "XT-PIC", .name = "XT-PIC",
.mask = disable_8259A_irq, .mask = disable_8259A_irq,
.disable = disable_8259A_irq,
.unmask = enable_8259A_irq, .unmask = enable_8259A_irq,
.mask_ack = mask_and_ack_8259A, .mask_ack = mask_and_ack_8259A,
}; };
......
...@@ -230,10 +230,6 @@ static void default_enable(unsigned int irq) ...@@ -230,10 +230,6 @@ static void default_enable(unsigned int irq)
*/ */
static void default_disable(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);
} }
/* /*
...@@ -298,13 +294,18 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) ...@@ -298,13 +294,18 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
if (unlikely(desc->status & IRQ_INPROGRESS)) if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock; goto out_unlock;
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
kstat_cpu(cpu).irqs[irq]++; kstat_cpu(cpu).irqs[irq]++;
action = desc->action; 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; goto out_unlock;
}
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING);
desc->status |= IRQ_INPROGRESS; desc->status |= IRQ_INPROGRESS;
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
...@@ -396,11 +397,13 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) ...@@ -396,11 +397,13 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
/* /*
* If its disabled or no action available * 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; action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED))) { if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
desc->status |= IRQ_PENDING; desc->status |= IRQ_PENDING;
if (desc->chip->mask)
desc->chip->mask(irq);
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment