02_libata_add-locking-to-ata_scsi_error.patch

        SCSI EH can start before ata_qc_complete is completely
        complete.  so, latter part of ata_qc_complete can run
        side-by-side with ->eng_timeout(), interfering EH.

        This patch makes ata_scsi_error() to grab and release host_set
        lock before invoking ->eng_timeout().

        Note: host_failed decrementing and eh_cmd_q banging are moved
        above ->eng_timeout() invocation such that they're done while
        holding the lock.

Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>

 libata-scsi.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

Index: work/drivers/scsi/libata-scsi.c
===================================================================
--- work.orig/drivers/scsi/libata-scsi.c        2005-08-20 22:34:02.000000000 
+0900
+++ work/drivers/scsi/libata-scsi.c     2005-08-20 23:13:40.000000000 +0900
@@ -373,12 +373,14 @@ int ata_scsi_slave_config(struct scsi_de
 
 int ata_scsi_error(struct Scsi_Host *host)
 {
-       struct ata_port *ap;
+       struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
 
        DPRINTK("ENTER\n");
 
-       ap = (struct ata_port *) &host->hostdata[0];
-       ap->ops->eng_timeout(ap);
+       /* The following locking ensures that we enter eng_timeout
+        * after ata_qc_complete is complete.
+        */
+       spin_lock_irq(&ap->host_set->lock);
 
        /* TODO: this is per-command; when queueing is supported
         * this code will either change or move to a more
@@ -387,6 +389,10 @@ int ata_scsi_error(struct Scsi_Host *hos
        host->host_failed--;
        INIT_LIST_HEAD(&host->eh_cmd_q);
 
+       spin_unlock_irq(&ap->host_set->lock);
+
+       ap->ops->eng_timeout(ap);
+
        DPRINTK("EXIT\n");
        return 0;
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to