Commit 4ebbb5cf authored by Vikas Chaudhary's avatar Vikas Chaudhary Committed by James Bottomley

[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: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 58e2bbe9
...@@ -2828,37 +2828,28 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) ...@@ -2828,37 +2828,28 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
int rval = QLA_ERROR; int rval = QLA_ERROR;
int i; int i;
uint32_t old_count, count; uint32_t old_count, count;
int need_reset = 0, peg_stuck = 1; int need_reset = 0;
need_reset = ha->isp_ops->need_reset(ha); 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) { if (need_reset) {
/* We are trying to perform a recovery here. */ /* 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); ha->isp_ops->rom_lock_recovery(ha);
goto dev_initialize;
} else { } else {
/* Start of day for this ha context. */ old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
if (peg_stuck) { for (i = 0; i < 10; i++) {
/* Either we are the first or recovery in progress. */ msleep(200);
ha->isp_ops->rom_lock_recovery(ha); count = qla4_8xxx_rd_direct(ha,
goto dev_initialize; QLA8XXX_PEG_ALIVE_COUNTER);
} else { if (count != old_count) {
/* Firmware already running. */ rval = QLA_SUCCESS;
rval = QLA_SUCCESS; goto dev_ready;
goto dev_ready; }
} }
ha->isp_ops->rom_lock_recovery(ha);
} }
dev_initialize:
/* set to DEV_INITIALIZING */ /* set to DEV_INITIALIZING */
ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment