Skip to content

Commit da7c21b

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix command flush during TMF
For each TMF request, driver iterates through each qpair and flushes commands associated to the TMF. At the end of the qpair flush, a Marker is used to complete the flush transaction. This process was repeated for each qpair. The multiple flush and marker for this TMF request seems to cause confusion for FW. Instead, 1 flush is sent to FW. Driver would wait for FW to go through all the I/Os on each qpair to be read then return. Driver then closes out the transaction with a Marker. Cc: stable@vger.kernel.org Fixes: d90171d ("scsi: qla2xxx: Multi-que support for TMF") Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230714070104.40052-5-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent a8ec192 commit da7c21b

File tree

3 files changed

+45
-39
lines changed

3 files changed

+45
-39
lines changed

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,12 +2002,11 @@ qla2x00_tmf_iocb_timeout(void *data)
20022002
int rc, h;
20032003
unsigned long flags;
20042004

2005-
if (sp->type == SRB_MARKER) {
2006-
complete(&tmf->u.tmf.comp);
2007-
return;
2008-
}
2005+
if (sp->type == SRB_MARKER)
2006+
rc = QLA_FUNCTION_FAILED;
2007+
else
2008+
rc = qla24xx_async_abort_cmd(sp, false);
20092009

2010-
rc = qla24xx_async_abort_cmd(sp, false);
20112010
if (rc) {
20122011
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
20132012
for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
@@ -2129,15 +2128,27 @@ static void qla2x00_tmf_sp_done(srb_t *sp, int res)
21292128
complete(&tmf->u.tmf.comp);
21302129
}
21312130

2131+
static int qla_tmf_wait(struct tmf_arg *arg)
2132+
{
2133+
/* there are only 2 types of error handling that reaches here, lun or target reset */
2134+
if (arg->flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET | TCF_CLEAR_TASK_SET))
2135+
return qla2x00_eh_wait_for_pending_commands(arg->vha,
2136+
arg->fcport->d_id.b24, arg->lun, WAIT_LUN);
2137+
else
2138+
return qla2x00_eh_wait_for_pending_commands(arg->vha,
2139+
arg->fcport->d_id.b24, arg->lun, WAIT_TARGET);
2140+
}
2141+
21322142
static int
21332143
__qla2x00_async_tm_cmd(struct tmf_arg *arg)
21342144
{
21352145
struct scsi_qla_host *vha = arg->vha;
21362146
struct srb_iocb *tm_iocb;
21372147
srb_t *sp;
21382148
int rval = QLA_FUNCTION_FAILED;
2139-
21402149
fc_port_t *fcport = arg->fcport;
2150+
u32 chip_gen, login_gen;
2151+
u64 jif;
21412152

21422153
if (TMF_NOT_READY(arg->fcport)) {
21432154
ql_dbg(ql_dbg_taskm, vha, 0x8032,
@@ -2182,8 +2193,27 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
21822193
"TM IOCB failed (%x).\n", rval);
21832194
}
21842195

2185-
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw))
2186-
rval = qla26xx_marker(arg);
2196+
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
2197+
chip_gen = vha->hw->chip_reset;
2198+
login_gen = fcport->login_gen;
2199+
2200+
jif = jiffies;
2201+
if (qla_tmf_wait(arg)) {
2202+
ql_log(ql_log_info, vha, 0x803e,
2203+
"Waited %u ms Nexus=%ld:%06x:%llu.\n",
2204+
jiffies_to_msecs(jiffies - jif), vha->host_no,
2205+
fcport->d_id.b24, arg->lun);
2206+
}
2207+
2208+
if (chip_gen == vha->hw->chip_reset && login_gen == fcport->login_gen) {
2209+
rval = qla26xx_marker(arg);
2210+
} else {
2211+
ql_log(ql_log_info, vha, 0x803e,
2212+
"Skip Marker due to disruption. Nexus=%ld:%06x:%llu.\n",
2213+
vha->host_no, fcport->d_id.b24, arg->lun);
2214+
rval = QLA_FUNCTION_FAILED;
2215+
}
2216+
}
21872217

21882218
done_free_sp:
21892219
/* ref: INIT */
@@ -2261,9 +2291,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
22612291
uint32_t tag)
22622292
{
22632293
struct scsi_qla_host *vha = fcport->vha;
2264-
struct qla_qpair *qpair;
22652294
struct tmf_arg a;
2266-
int i, rval = QLA_SUCCESS;
2295+
int rval = QLA_SUCCESS;
22672296

22682297
if (TMF_NOT_READY(fcport))
22692298
return QLA_SUSPENDED;
@@ -2283,34 +2312,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
22832312
if (qla_get_tmf(&a))
22842313
return QLA_FUNCTION_FAILED;
22852314

2286-
if (vha->hw->mqenable) {
2287-
for (i = 0; i < vha->hw->num_qpairs; i++) {
2288-
qpair = vha->hw->queue_pair_map[i];
2289-
if (!qpair)
2290-
continue;
2291-
2292-
if (TMF_NOT_READY(fcport)) {
2293-
ql_log(ql_log_warn, vha, 0x8026,
2294-
"Unable to send TM due to disruption.\n");
2295-
rval = QLA_SUSPENDED;
2296-
break;
2297-
}
2298-
2299-
a.qpair = qpair;
2300-
a.flags = flags|TCF_NOTMCMD_TO_TARGET;
2301-
rval = __qla2x00_async_tm_cmd(&a);
2302-
if (rval)
2303-
break;
2304-
}
2305-
}
2306-
2307-
if (rval)
2308-
goto bailout;
2309-
23102315
a.qpair = vha->hw->base_qpair;
23112316
rval = __qla2x00_async_tm_cmd(&a);
23122317

2313-
bailout:
23142318
qla_put_tmf(&a);
23152319
return rval;
23162320
}

drivers/scsi/qla2xxx/qla_iocb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3881,6 +3881,7 @@ qla_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk)
38813881
{
38823882
mrk->entry_type = MARKER_TYPE;
38833883
mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier;
3884+
mrk->handle = make_handle(sp->qpair->req->id, sp->handle);
38843885
if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) {
38853886
mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id);
38863887
int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun);

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,8 +1488,9 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
14881488
goto eh_reset_failed;
14891489
}
14901490
err = 3;
1491-
if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
1492-
sdev->lun, WAIT_LUN) != QLA_SUCCESS) {
1491+
if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24,
1492+
cmd->device->lun,
1493+
WAIT_LUN) != QLA_SUCCESS) {
14931494
ql_log(ql_log_warn, vha, 0x800d,
14941495
"wait for pending cmds failed for cmd=%p.\n", cmd);
14951496
goto eh_reset_failed;
@@ -1555,8 +1556,8 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
15551556
goto eh_reset_failed;
15561557
}
15571558
err = 3;
1558-
if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
1559-
0, WAIT_TARGET) != QLA_SUCCESS) {
1559+
if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24, 0,
1560+
WAIT_TARGET) != QLA_SUCCESS) {
15601561
ql_log(ql_log_warn, vha, 0x800d,
15611562
"wait for pending cmds failed for cmd=%p.\n", cmd);
15621563
goto eh_reset_failed;

0 commit comments

Comments
 (0)