It smells like ide_do_request forgets to enable interrupts when
request queue is empty.
drivers/ide/ide-io.c:
void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
{
ide_drive_t *drive;
ide_hwif_t *hwif;
struct request *rq;
ide_startstop_t startstop;
/* for atari only: POSSIBLY BROKEN HERE(?) */
ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);
/* necessary paranoia: ensure IRQs are masked on local CPU */
local_irq_disable();
^^^^^^^^
[...]
if (drive == NULL) {
[...]
if (sleep) {
[...]
} else {
/* Ugly, but how can we sleep for the lock
* otherwise? perhaps from tq_disk?
*/
/* for atari only */
ide_release_lock(&ide_intr_lock);
hwgroup->busy = 0;
}
/* no more work for this hwgroup (for now) */
return;
Oops. local_irq_disable remains in effect
[...]
spin_unlock(&io_request_lock);
local_irq_enable();
^^^^^^^^^^^^^^^^^^^
/* allow other IRQs while we start this request */
startstop = start_request(drive, rq);
spin_lock_irq(&io_request_lock);
if (masked_irq && hwif->irq != masked_irq)
enable_irq(hwif->irq);
if (startstop == ide_stopped)
hwgroup->busy = 0;
Ironically it does not release ide_intr_lock in this case but we
are not on m68k so we do not care :)
Could you please try to add local_irq_enable() before ide_release_lock() above and see if it helps?
It has been reported to have fixed fix problems for other people. OTOH
I did have sevral hard lockups with this so there may be more subtle
problems issues.
-andrey
-
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/