Skip to content

Commit

Permalink
genirq: Distangle edge handler entry
Browse files Browse the repository at this point in the history
If the interrupt is disabled or has no action, then we should not call
the poll check. Separate the checks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Thomas Gleixner authored and Rafael J. Wysocki committed Sep 1, 2014
1 parent c4df606 commit c3d7acd
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions kernel/irq/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,19 +540,29 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);

desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);

/*
* If we're currently running this IRQ, or its disabled,
* we shouldn't process the IRQ. Mark it pending, handle
* the necessary masking and go out
* If the handler is currently running, mark it pending,
* handle the necessary masking and go out
*/
if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
if (unlikely(irqd_irq_inprogress(&desc->irq_data))) {
if (!irq_check_poll(desc)) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
goto out_unlock;
}
}

/*
* If its disabled or no action available then mask it and get
* out of here.
*/
if (irqd_irq_disabled(&desc->irq_data) || !desc->action) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
goto out_unlock;
}

kstat_incr_irqs_this_cpu(irq, desc);

/* Start handling the irq */
Expand Down Expand Up @@ -601,18 +611,27 @@ void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);

desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);

/*
* If we're currently running this IRQ, or its disabled,
* we shouldn't process the IRQ. Mark it pending, handle
* the necessary masking and go out
* If the handler is currently running, mark it pending,
* handle the necessary masking and go out
*/
if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
if (unlikely(irqd_irq_inprogress(&desc->irq_data))) {
if (!irq_check_poll(desc)) {
desc->istate |= IRQS_PENDING;
goto out_eoi;
}
}

/*
* If its disabled or no action available then mask it and get
* out of here.
*/
if (irqd_irq_disabled(&desc->irq_data) || !desc->action) {
desc->istate |= IRQS_PENDING;
goto out_eoi;
}

kstat_incr_irqs_this_cpu(irq, desc);

do {
Expand Down

0 comments on commit c3d7acd

Please sign in to comment.