[SCSI] qla4xxx: Reduce rom-lock contention during reset recovery.

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>
This commit is contained in:
Vikas Chaudhary 2013-12-16 06:49:45 -05:00 committed by James Bottomley
parent 58e2bbe985
commit 4ebbb5cf64

View 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,