Re: 2.4.21-rc: lost interrupt wgen usinf atapi cdrom-drive

Andrey Borzenkov (arvidjaar@mail.ru)
Tue, 13 May 2003 10:21:19 +0400


> i upgraded the linux kernel of my computer from 2.4.21-pre4 to
> 2.4.21-rc2 and got the following messages in syslog when using my
> atapi-cdrom drive:
>
> May 12 09:42:42 pcew80 kernel: sr0: scsi3-mmc drive: 24x/24x writer
> cd/rw xa/form2 cdda tray
> May 12 09:42:42 pcew80 kernel: Uniform CD-ROM driver Revision: 3.12
> May 12 09:42:42 pcew80 kernel: sr1: scsi-1 drive
> May 12 09:42:42 pcew80 kernel: hdc: attached ide-cdrom driver.
> May 12 09:42:42 pcew80 kernel: hdc: ATAPI 48X CD-ROM drive, 120kB Cache,
> UDMA(33)
> May 12 09:42:42 pcew80 kernel: ISO 9660 Extensions: Microsoft Joliet
> Level 3
> May 12 09:42:52 pcew80 kernel: hdc: DMA interrupt recovery
> May 12 09:42:52 pcew80 kernel: hdc: lost interrupt
> May 12 09:42:52 pcew80 kernel: hdc: status timeout: status=0xd0 { Busy }
> May 12 09:42:52 pcew80 kernel: hdc: status timeout: error=0x00
> May 12 09:42:52 pcew80 kernel: hdc: DMA disabled
> May 12 09:42:52 pcew80 kernel: hdc: drive not ready for command
> May 12 09:42:52 pcew80 kernel: hdc: ATAPI reset complete

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/