[SCSI] qla4xxx: Reduce rom-lock contention during reset recovery.
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>
Mon, 16 Dec 2013 11:49:45 +0000 (06:49 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:14 +0000 (10:19 -0700)
Issue:
Driver holds rom-lock for too long during reset recovery.

During adapter reset testing, it was found that the driver
holds the rom-lock for too long, because of which other
drivers fail to acquire the rom-lock, leading to reset
failures.
The primary cause is, in the bootstrap code, while
holding the rom-lock, the driver checks if the peg is
halted, causing a 2 second contention.

Fix:
When a reset recovery starts, the driver deduces the cause, and
sets appropriate flags in watchdog & recover_adapter routines.
This flag should be used to determine if bootstrap is invoked
from probe or reset context, reducing the rom-lock footprint of
the drivers.

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_nx.c

index d2040b4..63328c8 100644 (file)
@@ -2828,37 +2828,28 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
        int rval = QLA_ERROR;
        int i;
        uint32_t old_count, count;
-       int need_reset = 0, peg_stuck = 1;
+       int need_reset = 0;
 
        need_reset = ha->isp_ops->need_reset(ha);
-       old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
-
-       for (i = 0; i < 10; i++) {
-               msleep(200);
-               count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
-               if (count != old_count)
-                       peg_stuck = 0;
-       }
 
        if (need_reset) {
                /* We are trying to perform a recovery here. */
-               if (peg_stuck)
+               if (test_bit(AF_FW_RECOVERY, &ha->flags))
                        ha->isp_ops->rom_lock_recovery(ha);
-               goto dev_initialize;
        } else  {
-               /* Start of day for this ha context. */
-               if (peg_stuck) {
-                       /* Either we are the first or recovery in progress. */
-                       ha->isp_ops->rom_lock_recovery(ha);
-                       goto dev_initialize;
-               } else {
-                       /* Firmware already running. */
-                       rval = QLA_SUCCESS;
-                       goto dev_ready;
+               old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
+               for (i = 0; i < 10; i++) {
+                       msleep(200);
+                       count = qla4_8xxx_rd_direct(ha,
+                                                   QLA8XXX_PEG_ALIVE_COUNTER);
+                       if (count != old_count) {
+                               rval = QLA_SUCCESS;
+                               goto dev_ready;
+                       }
                }
+               ha->isp_ops->rom_lock_recovery(ha);
        }
 
-dev_initialize:
        /* set to DEV_INITIALIZING */
        ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
        qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,