[SCSI] qla4xxx: Fix pending IO completion in reset path before initiating chip reset
authorTej Parkash <tej.parkash@qlogic.com>
Mon, 16 Dec 2013 11:49:43 +0000 (06:49 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:14 +0000 (10:19 -0700)
Issue:
Pending IO wait does not complete after triggering Graceful reset,
causing ack timeout and call traces.

Fix:
1. Reducing the IO command wait timeout before triggering reset,
   as logically also timeout should be less than reset timeout (10sec).
2. Moving the abort IO after chip reset, because only after
   chip reset, driver owns the IO otherwise it is with firmware and can
   still revert back with response.

Signed-off-by: Tej Parkash <tej.parkash@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_os.c

index 33eae2e12dbaabf635a8ce6e74642e18a0bf083f..c2deaa0085583f5502567a8db19610969dd287b3 100644 (file)
 #define ADAPTER_INIT_TOV               30
 #define ADAPTER_RESET_TOV              180
 #define EXTEND_CMD_TOV                 60
-#define WAIT_CMD_TOV                   30
+#define WAIT_CMD_TOV                   5
 #define EH_WAIT_CMD_TOV                        120
 #define FIRMWARE_UP_TOV                        60
 #define RESET_FIRMWARE_TOV             30
index 3fec116e2724f29e5c8a1e5afe1cd6b243561959..a27da31c4ffd4c8276831036fe10c1d7b17bf0c1 100644 (file)
@@ -4561,11 +4561,19 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
        uint32_t index = 0;
        unsigned long flags;
        struct scsi_cmnd *cmd;
+       unsigned long wtime;
+       uint32_t wtmo;
 
-       unsigned long wtime = jiffies + (WAIT_CMD_TOV * HZ);
+       if (is_qla40XX(ha))
+               wtmo = WAIT_CMD_TOV;
+       else
+               wtmo = ha->nx_reset_timeout / 2;
 
-       DEBUG2(ql4_printk(KERN_INFO, ha, "Wait up to %d seconds for cmds to "
-           "complete\n", WAIT_CMD_TOV));
+       wtime = jiffies + (wtmo * HZ);
+
+       DEBUG2(ql4_printk(KERN_INFO, ha,
+                         "Wait up to %u seconds for cmds to complete\n",
+                         wtmo));
 
        while (!time_after_eq(jiffies, wtime)) {
                spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -4868,11 +4876,11 @@ chip_reset:
                        qla4xxx_cmd_wait(ha);
 
                qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
-               qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
                DEBUG2(ql4_printk(KERN_INFO, ha,
                    "scsi%ld: %s - Performing chip reset..\n",
                    ha->host_no, __func__));
                status = ha->isp_ops->reset_chip(ha);
+               qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
        }
 
        /* Flush any pending ddb changed AENs */