[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20070130093302.GA24436@elte.hu>
Date: Tue, 30 Jan 2007 10:33:03 +0100
From: Ingo Molnar <mingo@...e.hu>
To: linux-kernel@...r.kernel.org
Cc: Andrew Morton <akpm@...l.org>, Thomas Gleixner <tglx@...utronix.de>
Subject: [patch] genirq: do not mask interrupts by default
Subject: [patch] genirq: do not mask interrupts by default
From: Ingo Molnar <mingo@...e.hu>
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@...e.hu>
---
arch/i386/kernel/i8259.c | 1 +
arch/x86_64/kernel/i8259.c | 1 +
kernel/irq/chip.c | 17 ++++++++++-------
3 files changed, 12 insertions(+), 7 deletions(-)
Index: linux/arch/i386/kernel/i8259.c
===================================================================
--- linux.orig/arch/i386/kernel/i8259.c
+++ linux/arch/i386/kernel/i8259.c
@@ -41,6 +41,7 @@ static void mask_and_ack_8259A(unsigned
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,
};
Index: linux/arch/x86_64/kernel/i8259.c
===================================================================
--- linux.orig/arch/x86_64/kernel/i8259.c
+++ linux/arch/x86_64/kernel/i8259.c
@@ -103,6 +103,7 @@ static void mask_and_ack_8259A(unsigned
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,
};
Index: linux/kernel/irq/chip.c
===================================================================
--- linux.orig/kernel/irq/chip.c
+++ linux/kernel/irq/chip.c
@@ -202,10 +202,6 @@ static void default_enable(unsigned int
*/
static void default_disable(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
-
- if (!(desc->status & IRQ_DELAYED_DISABLE))
- desc->chip->mask(irq);
}
/*
@@ -270,13 +266,18 @@ handle_simple_irq(unsigned int irq, stru
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);
@@ -368,11 +369,13 @@ handle_fasteoi_irq(unsigned int irq, str
/*
* 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;
}
----- End forwarded message -----
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists