mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
[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:
parent
58e2bbe985
commit
4ebbb5cf64
1 changed files with 12 additions and 21 deletions
|
@ -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. */
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue