Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+12 −21
Original line number Diff line number Diff line
@@ -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)
			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. */
		if (test_bit(AF_FW_RECOVERY, &ha->flags))
			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,