lkml.org 
[lkml]   [2003]   [Oct]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subject[RFC] disable_irq()/enable_irq() semantics and ide-probe.c
	Current code (at least on x86 and alpha) appears to assume that
you can't call disable_irq()/enable_irq() unless you have registered
that irq.

However, ide-probe.c::probe_hwif() contains the following:
/*
* We must always disable IRQ, as probe_for_drive will assert IRQ, but
* we'll install our IRQ driver much later...
*/
irqd = hwif->irq;
if (irqd)
disable_irq(hwif->irq);
and later
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
*/
if (irqd)
enable_irq(irqd);

That happens *way* before we call register_irq(). Current tree barfs on
that in all sorts of interesting ways. Most notably, we get irq enabled
and with NULL ->action for a while. If an interrupt comes during that
time, we'll get IRQ_INPROGRESS set and not reset until later register_irq()
(see handle_irq() for details). Note that calling disable_irq() after that
will kill us on SMP - it will spin waiting for IRQ_INPROGRESS to go away.

Moreover, if somebody calls register_irq() while we are at it, we'll get
->depth reset to 0. enable_irq() will try to decrement depth and will get
very unhappy about the situation.

What do we really want to do here? I see only two variants:
a) allow enable_irq()/disable_irq() regardless of having the thing
registered. IRQ_DISABLED would be set iff ->depth is positive or ->action
is NULL. register_irq() wouldn't touch the ->depth and would enable IRQ
only if ->depth is 0. enable_irq() would not enable the thing unless ->action
was non-NULL. That would work, but I wouldn't bet a dime on correctness -
e.g. currently disable_irq() followed by free_irq() works fine and drivers
might very well leave ->depth positive when they are removed. With new
scheme that would be deadly.
b) have ide-probe.c register a dummy handler for that period.
Then it would be allowed to do what it does. Said handler would simply
return IRQ_NONE and be done with that. Add BUG() to disable_irq()/enable_irq()
for cases when they are called with NULL ->action.

Note that scenario above is absolutely real - 2.4.21 and later
hang on DS10 since their IDE chipset (alim15x3.c) does generate an interrupt
after the probe code had called enable_irq(). With obvious results -
ide_intr() is never called afterwards. On 2.6 it doesn't happen only
because register_irq() forcibly drops IRQ_INPROGRESS, which hides that
problem, but doesn't help with other scenarios (e.g. somebody sharing the
same IRQ and doing register_irq() before we call enable_irq()).

Comments?
-
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/

\
 
 \ /
  Last update: 2005-03-22 13:49    [W:0.107 / U:0.152 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site