[PATCH] libata: Prevent the interrupt handler from completing a command twice

Problem:
During the libata CD-ROM stress test, sometimes the "BUG: timeout
without command" error is seen.

Root cause:
Unexpected interrupt occurs after the ata_qc_complete() is called,
but before the SCSI error handler. The interrupt handler is invoked
before the SCSI error handler, and it clears the command by calling
ata_qc_complete() again. Later when the SCSI error handler is run,
the ata_queued_cmd is already gone, causing the "BUG: timeout without
command" error.

Changes:
- Use the ATA_QCFLAG_ACTIVE flag to prevent the interrupt handler
from completing the command twice, before the scsi_error_handler.

Signed-off-by: Albert Lee <albertcc@tw.ibm.com>

authored by

Albert Lee and committed by
Jeff Garzik
21b1ed74 f85bdb9c

+4 -2
+4 -2
drivers/scsi/libata-core.c
··· 2539 ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); 2540 qc->dma_dir = DMA_FROM_DEVICE; 2541 2542 - memset(&qc->cdb, 0, sizeof(ap->cdb_len)); 2543 qc->cdb[0] = REQUEST_SENSE; 2544 qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; 2545 ··· 2811 2812 /* call completion callback */ 2813 rc = qc->complete_fn(qc, drv_stat); 2814 2815 /* if callback indicates not to complete command (non-zero), 2816 * return immediately ··· 3230 struct ata_queued_cmd *qc; 3231 3232 qc = ata_qc_from_tag(ap, ap->active_tag); 3233 - if (qc && (!(qc->tf.ctl & ATA_NIEN))) 3234 handled |= ata_host_intr(ap, qc); 3235 } 3236 }
··· 2539 ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); 2540 qc->dma_dir = DMA_FROM_DEVICE; 2541 2542 + memset(&qc->cdb, 0, ap->cdb_len); 2543 qc->cdb[0] = REQUEST_SENSE; 2544 qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; 2545 ··· 2811 2812 /* call completion callback */ 2813 rc = qc->complete_fn(qc, drv_stat); 2814 + qc->flags &= ~ATA_QCFLAG_ACTIVE; 2815 2816 /* if callback indicates not to complete command (non-zero), 2817 * return immediately ··· 3229 struct ata_queued_cmd *qc; 3230 3231 qc = ata_qc_from_tag(ap, ap->active_tag); 3232 + if (qc && (!(qc->tf.ctl & ATA_NIEN)) && 3233 + (qc->flags & ATA_QCFLAG_ACTIVE)) 3234 handled |= ata_host_intr(ap, qc); 3235 } 3236 }