Commit 5d3148d8 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix TMF leak through



Task management can retry up to 5 times when FW resource becomes bottle
neck. Between the retries, there is a short sleep.  Current code assumes
the chip has not reset or session has not changed.

Check for chip reset or session change before sending Task management.

Cc: stable@vger.kernel.org
Fixes: 9803fb5d ("scsi: qla2xxx: Fix task management cmd failure")
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Link: https://lore.kernel.org/r/20230714070104.40052-9-njavali@marvell.com


Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 8ebaa451
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -2038,10 +2038,14 @@ static void qla_marker_sp_done(srb_t *sp, int res)
	complete(&tmf->u.tmf.comp);
}

#define  START_SP_W_RETRIES(_sp, _rval) \
#define  START_SP_W_RETRIES(_sp, _rval, _chip_gen, _login_gen) \
{\
	int cnt = 5; \
	do { \
		if (_chip_gen != sp->vha->hw->chip_reset || _login_gen != sp->fcport->login_gen) {\
			_rval = EINVAL; \
			break; \
		} \
		_rval = qla2x00_start_sp(_sp); \
		if (_rval == EAGAIN) \
			msleep(1); \
@@ -2064,6 +2068,7 @@ qla26xx_marker(struct tmf_arg *arg)
	srb_t *sp;
	int rval = QLA_FUNCTION_FAILED;
	fc_port_t *fcport = arg->fcport;
	u32 chip_gen, login_gen;

	if (TMF_NOT_READY(arg->fcport)) {
		ql_dbg(ql_dbg_taskm, vha, 0x8039,
@@ -2073,6 +2078,9 @@ qla26xx_marker(struct tmf_arg *arg)
		return QLA_SUSPENDED;
	}

	chip_gen = vha->hw->chip_reset;
	login_gen = fcport->login_gen;

	/* ref: INIT */
	sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
	if (!sp)
@@ -2090,7 +2098,7 @@ qla26xx_marker(struct tmf_arg *arg)
	tm_iocb->u.tmf.loop_id = fcport->loop_id;
	tm_iocb->u.tmf.vp_index = vha->vp_idx;

	START_SP_W_RETRIES(sp, rval);
	START_SP_W_RETRIES(sp, rval, chip_gen, login_gen);

	ql_dbg(ql_dbg_taskm, vha, 0x8006,
	    "Async-marker hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n",
@@ -2159,6 +2167,9 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
		return QLA_SUSPENDED;
	}

	chip_gen = vha->hw->chip_reset;
	login_gen = fcport->login_gen;

	/* ref: INIT */
	sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
	if (!sp)
@@ -2176,7 +2187,7 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
	tm_iocb->u.tmf.flags = arg->flags;
	tm_iocb->u.tmf.lun = arg->lun;

	START_SP_W_RETRIES(sp, rval);
	START_SP_W_RETRIES(sp, rval, chip_gen, login_gen);

	ql_dbg(ql_dbg_taskm, vha, 0x802f,
	    "Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n",
@@ -2195,9 +2206,6 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
	}

	if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
		chip_gen = vha->hw->chip_reset;
		login_gen = fcport->login_gen;

		jif = jiffies;
		if (qla_tmf_wait(arg)) {
			ql_log(ql_log_info, vha, 0x803e,