Skip to content

Commit 9803fb5

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix task management cmd failure
Task management cmd failed with status 30h which means FW is not able to finish processing one task management before another task management for the same lun. Hence add wait for completion of marker to space it out. Reported-by: kernel test robot <[email protected]> Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Cc: [email protected] Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Himanshu Madhani <[email protected] <mailto:[email protected]>> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent d90171d commit 9803fb5

File tree

4 files changed

+139
-23
lines changed

4 files changed

+139
-23
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ struct tmf_arg {
471471
struct scsi_qla_host *vha;
472472
u64 lun;
473473
u32 flags;
474+
uint8_t modifier;
474475
};
475476

476477
struct els_logo_payload {
@@ -552,6 +553,10 @@ struct srb_iocb {
552553
uint32_t data;
553554
struct completion comp;
554555
__le16 comp_status;
556+
557+
uint8_t modifier;
558+
uint8_t vp_index;
559+
uint16_t loop_id;
555560
} tmf;
556561
struct {
557562
#define SRB_FXDISC_REQ_DMA_VALID BIT_0
@@ -655,6 +660,7 @@ struct srb_iocb {
655660
#define SRB_SA_UPDATE 25
656661
#define SRB_ELS_CMD_HST_NOLOGIN 26
657662
#define SRB_SA_REPLACE 27
663+
#define SRB_MARKER 28
658664

659665
struct qla_els_pt_arg {
660666
u8 els_opcode;

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 86 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,6 +2013,80 @@ qla2x00_tmf_iocb_timeout(void *data)
20132013
}
20142014
}
20152015

2016+
static void qla_marker_sp_done(srb_t *sp, int res)
2017+
{
2018+
struct srb_iocb *tmf = &sp->u.iocb_cmd;
2019+
2020+
if (res != QLA_SUCCESS)
2021+
ql_dbg(ql_dbg_taskm, sp->vha, 0x8004,
2022+
"Async-marker fail hdl=%x portid=%06x ctrl=%x lun=%lld qp=%d.\n",
2023+
sp->handle, sp->fcport->d_id.b24, sp->u.iocb_cmd.u.tmf.flags,
2024+
sp->u.iocb_cmd.u.tmf.lun, sp->qpair->id);
2025+
2026+
complete(&tmf->u.tmf.comp);
2027+
}
2028+
2029+
#define START_SP_W_RETRIES(_sp, _rval) \
2030+
{\
2031+
int cnt = 5; \
2032+
do { \
2033+
_rval = qla2x00_start_sp(_sp); \
2034+
if (_rval == EAGAIN) \
2035+
msleep(1); \
2036+
else \
2037+
break; \
2038+
cnt--; \
2039+
} while (cnt); \
2040+
}
2041+
2042+
static int
2043+
qla26xx_marker(struct tmf_arg *arg)
2044+
{
2045+
struct scsi_qla_host *vha = arg->vha;
2046+
struct srb_iocb *tm_iocb;
2047+
srb_t *sp;
2048+
int rval = QLA_FUNCTION_FAILED;
2049+
fc_port_t *fcport = arg->fcport;
2050+
2051+
/* ref: INIT */
2052+
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
2053+
if (!sp)
2054+
goto done;
2055+
2056+
sp->type = SRB_MARKER;
2057+
sp->name = "marker";
2058+
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha), qla_marker_sp_done);
2059+
sp->u.iocb_cmd.timeout = qla2x00_tmf_iocb_timeout;
2060+
2061+
tm_iocb = &sp->u.iocb_cmd;
2062+
init_completion(&tm_iocb->u.tmf.comp);
2063+
tm_iocb->u.tmf.modifier = arg->modifier;
2064+
tm_iocb->u.tmf.lun = arg->lun;
2065+
tm_iocb->u.tmf.loop_id = fcport->loop_id;
2066+
tm_iocb->u.tmf.vp_index = vha->vp_idx;
2067+
2068+
START_SP_W_RETRIES(sp, rval);
2069+
2070+
ql_dbg(ql_dbg_taskm, vha, 0x8006,
2071+
"Async-marker hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n",
2072+
sp->handle, fcport->loop_id, fcport->d_id.b24,
2073+
arg->modifier, arg->lun, sp->qpair->id, rval);
2074+
2075+
if (rval != QLA_SUCCESS) {
2076+
ql_log(ql_log_warn, vha, 0x8031,
2077+
"Marker IOCB failed (%x).\n", rval);
2078+
goto done_free_sp;
2079+
}
2080+
2081+
wait_for_completion(&tm_iocb->u.tmf.comp);
2082+
2083+
done_free_sp:
2084+
/* ref: INIT */
2085+
kref_put(&sp->cmd_kref, qla2x00_sp_release);
2086+
done:
2087+
return rval;
2088+
}
2089+
20162090
static void qla2x00_tmf_sp_done(srb_t *sp, int res)
20172091
{
20182092
struct srb_iocb *tmf = &sp->u.iocb_cmd;
@@ -2026,7 +2100,6 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
20262100
struct scsi_qla_host *vha = arg->vha;
20272101
struct srb_iocb *tm_iocb;
20282102
srb_t *sp;
2029-
unsigned long flags;
20302103
int rval = QLA_FUNCTION_FAILED;
20312104

20322105
fc_port_t *fcport = arg->fcport;
@@ -2048,11 +2121,12 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
20482121
tm_iocb->u.tmf.flags = arg->flags;
20492122
tm_iocb->u.tmf.lun = arg->lun;
20502123

2051-
rval = qla2x00_start_sp(sp);
2124+
START_SP_W_RETRIES(sp, rval);
2125+
20522126
ql_dbg(ql_dbg_taskm, vha, 0x802f,
2053-
"Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x ctrl=%x.\n",
2054-
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
2055-
fcport->d_id.b.area, fcport->d_id.b.al_pa, arg->flags);
2127+
"Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n",
2128+
sp->handle, fcport->loop_id, fcport->d_id.b24,
2129+
arg->flags, arg->lun, sp->qpair->id, rval);
20562130

20572131
if (rval != QLA_SUCCESS)
20582132
goto done_free_sp;
@@ -2065,17 +2139,8 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
20652139
"TM IOCB failed (%x).\n", rval);
20662140
}
20672141

2068-
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
2069-
flags = tm_iocb->u.tmf.flags;
2070-
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|
2071-
TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
2072-
flags = MK_SYNC_ID_LUN;
2073-
else
2074-
flags = MK_SYNC_ID;
2075-
2076-
qla2x00_marker(vha, sp->qpair,
2077-
sp->fcport->loop_id, arg->lun, flags);
2078-
}
2142+
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw))
2143+
rval = qla26xx_marker(arg);
20792144

20802145
done_free_sp:
20812146
/* ref: INIT */
@@ -2099,6 +2164,11 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
20992164
a.fcport = fcport;
21002165
a.lun = lun;
21012166

2167+
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
2168+
a.modifier = MK_SYNC_ID_LUN;
2169+
else
2170+
a.modifier = MK_SYNC_ID;
2171+
21022172
if (vha->hw->mqenable) {
21032173
for (i = 0; i < vha->hw->num_qpairs; i++) {
21042174
qpair = vha->hw->queue_pair_map[i];

drivers/scsi/qla2xxx/qla_iocb.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,21 +522,25 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
522522
return (QLA_FUNCTION_FAILED);
523523
}
524524

525+
mrk24 = (struct mrk_entry_24xx *)mrk;
526+
525527
mrk->entry_type = MARKER_TYPE;
526528
mrk->modifier = type;
527529
if (type != MK_SYNC_ALL) {
528530
if (IS_FWI2_CAPABLE(ha)) {
529-
mrk24 = (struct mrk_entry_24xx *) mrk;
530531
mrk24->nport_handle = cpu_to_le16(loop_id);
531532
int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
532533
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
533534
mrk24->vp_index = vha->vp_idx;
534-
mrk24->handle = make_handle(req->id, mrk24->handle);
535535
} else {
536536
SET_TARGET_ID(ha, mrk->target, loop_id);
537537
mrk->lun = cpu_to_le16((uint16_t)lun);
538538
}
539539
}
540+
541+
if (IS_FWI2_CAPABLE(ha))
542+
mrk24->handle = QLA_SKIP_HANDLE;
543+
540544
wmb();
541545

542546
qla2x00_start_iocbs(vha, req);
@@ -3853,9 +3857,9 @@ static int qla_get_iocbs_resource(struct srb *sp)
38533857
case SRB_NACK_LOGO:
38543858
case SRB_LOGOUT_CMD:
38553859
case SRB_CTRL_VP:
3856-
push_it_through = true;
3857-
fallthrough;
3860+
case SRB_MARKER:
38583861
default:
3862+
push_it_through = true;
38593863
get_exch = false;
38603864
}
38613865

@@ -3871,6 +3875,19 @@ static int qla_get_iocbs_resource(struct srb *sp)
38713875
return qla_get_fw_resources(sp->qpair, &sp->iores);
38723876
}
38733877

3878+
static void
3879+
qla_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk)
3880+
{
3881+
mrk->entry_type = MARKER_TYPE;
3882+
mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier;
3883+
if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) {
3884+
mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id);
3885+
int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun);
3886+
host_to_fcp_swap(mrk->lun, sizeof(mrk->lun));
3887+
mrk->vp_index = sp->u.iocb_cmd.u.tmf.vp_index;
3888+
}
3889+
}
3890+
38743891
int
38753892
qla2x00_start_sp(srb_t *sp)
38763893
{
@@ -3974,6 +3991,9 @@ qla2x00_start_sp(srb_t *sp)
39743991
case SRB_SA_REPLACE:
39753992
qla24xx_sa_replace_iocb(sp, pkt);
39763993
break;
3994+
case SRB_MARKER:
3995+
qla_marker_iocb(sp, pkt);
3996+
break;
39773997
default:
39783998
break;
39793999
}

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,6 +3750,28 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
37503750
return rc;
37513751
}
37523752

3753+
static void qla_marker_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
3754+
struct mrk_entry_24xx *pkt)
3755+
{
3756+
const char func[] = "MRK-IOCB";
3757+
srb_t *sp;
3758+
int res = QLA_SUCCESS;
3759+
3760+
if (!IS_FWI2_CAPABLE(vha->hw))
3761+
return;
3762+
3763+
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
3764+
if (!sp)
3765+
return;
3766+
3767+
if (pkt->entry_status) {
3768+
ql_dbg(ql_dbg_taskm, vha, 0x8025, "marker failure.\n");
3769+
res = QLA_COMMAND_ERROR;
3770+
}
3771+
sp->u.iocb_cmd.u.tmf.data = res;
3772+
sp->done(sp, res);
3773+
}
3774+
37533775
/**
37543776
* qla24xx_process_response_queue() - Process response queue entries.
37553777
* @vha: SCSI driver HA context
@@ -3863,9 +3885,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
38633885
(struct nack_to_isp *)pkt);
38643886
break;
38653887
case MARKER_TYPE:
3866-
/* Do nothing in this case, this check is to prevent it
3867-
* from falling into default case
3868-
*/
3888+
qla_marker_iocb_entry(vha, rsp->req, (struct mrk_entry_24xx *)pkt);
38693889
break;
38703890
case ABORT_IOCB_TYPE:
38713891
qla24xx_abort_iocb_entry(vha, rsp->req,

0 commit comments

Comments
 (0)