Skip to content

Commit 76d2160

Browse files
Ingo MolnarLinus Torvalds
authored andcommitted
[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: 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>
1 parent 1f2ea08 commit 76d2160

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

arch/i386/kernel/i8259.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static void mask_and_ack_8259A(unsigned int);
4141
static struct irq_chip i8259A_chip = {
4242
.name = "XT-PIC",
4343
.mask = disable_8259A_irq,
44+
.disable = disable_8259A_irq,
4445
.unmask = enable_8259A_irq,
4546
.mask_ack = mask_and_ack_8259A,
4647
};

arch/x86_64/kernel/i8259.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static void mask_and_ack_8259A(unsigned int);
103103
static struct irq_chip i8259A_chip = {
104104
.name = "XT-PIC",
105105
.mask = disable_8259A_irq,
106+
.disable = disable_8259A_irq,
106107
.unmask = enable_8259A_irq,
107108
.mask_ack = mask_and_ack_8259A,
108109
};

kernel/irq/chip.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,6 @@ static void default_enable(unsigned int irq)
230230
*/
231231
static void default_disable(unsigned int irq)
232232
{
233-
struct irq_desc *desc = irq_desc + irq;
234-
235-
if (!(desc->status & IRQ_DELAYED_DISABLE))
236-
desc->chip->mask(irq);
237233
}
238234

239235
/*
@@ -298,13 +294,18 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
298294

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

304299
action = desc->action;
305-
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
300+
if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
301+
if (desc->chip->mask)
302+
desc->chip->mask(irq);
303+
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
304+
desc->status |= IRQ_PENDING;
306305
goto out_unlock;
306+
}
307307

308+
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING);
308309
desc->status |= IRQ_INPROGRESS;
309310
spin_unlock(&desc->lock);
310311

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

397398
/*
398399
* If its disabled or no action available
399-
* keep it masked and get out of here
400+
* then mask it and get out of here:
400401
*/
401402
action = desc->action;
402403
if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
403404
desc->status |= IRQ_PENDING;
405+
if (desc->chip->mask)
406+
desc->chip->mask(irq);
404407
goto out;
405408
}
406409

0 commit comments

Comments
 (0)