Messages in this thread Patch in this message |  | | | Date | Thu, 1 Jun 2006 12:02:18 +0200 | | From | Ingo Molnar <> | | Subject | Re: [patch, -rc5-mm1] locking validator: special rule: 8390.c disable_irq() |
| |
* Alan Cox <alan@redhat.com> wrote:
> On Wed, May 31, 2006 at 11:47:29PM +0200, Ingo Molnar wrote: > > couldnt most of these problems be avoided by tracking whether a handler > > _ever_ returned a success status? That means that irqpoll could safely > > poll handlers for which we know that they somehow arent yet matched up > > to any IRQ line? > > But you may get random positive hits from this when a real IRQ for an > unrelated device happens to get delivered. We could poll enabled IRQs > first then disabled ones ?
hm, you are right. Actions that are registered to the wrong IRQ might still appear to 'work' by pure accident, if they also share the IRQ with another (correctly routed) action.
the basic problem isnt really the polling method that irqpoll does - it is the insensitivity of the IRQ_DISABLED flag: we dont know whether it's disabled because the driver wants it, or because it was screaming before. Maybe we could (ab-)use irq_desc->depth for that - if that is 0 but IRQ_DISABLED is set then you may ignore IRQ_DISABLED. Ok?
The patch below implements this logic, ontop of -rc5-mm2. Can you see any hole in it? (It built and booted up fine on x86_64 but i dont have any misrouted irqs.)
Ingo
------------------ Subject: fix irqpoll to honor disable_irq() From: Ingo Molnar <mingo@elte.hu> irqpoll/irqfixup ignored IRQ_DISABLED but that could cause lockups. So listen to desc->depth to correctly honor disable_irq(). Also, when an interrupt it screaming, set IRQ_DISABLED but do not touch ->depth.
Signed-off-by: Ingo Molnar <mingo@elte.hu> Index: linux/kernel/irq/spurious.c =================================================================== --- linux.orig/kernel/irq/spurious.c +++ linux/kernel/irq/spurious.c @@ -56,6 +56,15 @@ static int misrouted_irq(int irq, struct local_irq_disable(); /* Now clean up the flags */ spin_lock(&desc->lock); + /* + * NOTE: we only listen to desc->depth here, not to + * IRQ_DISABLED - which might have been set due to + * a screaming interrupt. + */ + if (desc->depth) { + spin_unlock(&desc->lock); + continue; + } action = desc->action; /* @@ -163,10 +172,12 @@ void note_interrupt(unsigned int irq, st __report_bad_irq(irq, desc, action_ret); /* * Now kill the IRQ + * + * We keep desc->depth unchanged - so that irqpoll can + * honor driver IRQ-disabling. */ printk(KERN_EMERG "Disabling IRQ #%d\n", irq); desc->status |= IRQ_DISABLED; - desc->depth = 1; desc->chip->disable(irq); } desc->irqs_unhandled = 0; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |