Re: [PATCH v2 2/7] qla2xxx: Fix task management cmd failure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> On Apr 28, 2023, at 12:53 AM, Nilesh Javali <njavali@xxxxxxxxxxx> wrote:
> 
> From: Quinn Tran <qutran@xxxxxxxxxxx>
> 
> 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 <lkp@xxxxxxxxx>
> Link: https://lore.kernel.org/oe-kbuild-all/202304271802.uCZfwQC1-lkp@xxxxxxxxx/
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx>
> Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx>
> ---
> v2:
> - Fix warning reported by kernel robot.
> 
> drivers/scsi/qla2xxx/qla_def.h  |   6 ++
> drivers/scsi/qla2xxx/qla_init.c | 102 +++++++++++++++++++++++++++-----
> drivers/scsi/qla2xxx/qla_iocb.c |  28 +++++++--
> drivers/scsi/qla2xxx/qla_isr.c  |  26 +++++++-
> 4 files changed, 139 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
> index d59e94ae0db4..0437e0150a50 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -472,6 +472,7 @@ struct tmf_arg {
> struct scsi_qla_host *vha;
> u64 lun;
> u32 flags;
> + uint8_t modifier;
> };
> 
> struct els_logo_payload {
> @@ -553,6 +554,10 @@ struct srb_iocb {
> uint32_t data;
> struct completion comp;
> __le16 comp_status;
> +
> + uint8_t modifier;
> + uint8_t vp_index;
> + uint16_t loop_id;
> } tmf;
> struct {
> #define SRB_FXDISC_REQ_DMA_VALID BIT_0
> @@ -656,6 +661,7 @@ struct srb_iocb {
> #define SRB_SA_UPDATE 25
> #define SRB_ELS_CMD_HST_NOLOGIN 26
> #define SRB_SA_REPLACE 27
> +#define SRB_MARKER 28
> 
> struct qla_els_pt_arg {
> u8 els_opcode;
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index 035d1984e2bd..2402b1402e0d 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -2013,6 +2013,80 @@ qla2x00_tmf_iocb_timeout(void *data)
> }
> }
> 
> +static void qla_marker_sp_done(srb_t *sp, int res)
> +{
> + struct srb_iocb *tmf = &sp->u.iocb_cmd;
> +
> + if (res != QLA_SUCCESS)
> + ql_dbg(ql_dbg_taskm, sp->vha, 0x8004,
> +    "Async-marker fail hdl=%x portid=%06x ctrl=%x lun=%lld qp=%d.\n",
> +    sp->handle, sp->fcport->d_id.b24, sp->u.iocb_cmd.u.tmf.flags,
> +    sp->u.iocb_cmd.u.tmf.lun, sp->qpair->id);
> +
> + complete(&tmf->u.tmf.comp);
> +}
> +
> +#define  START_SP_W_RETRIES(_sp, _rval) \
> +{\
> + int cnt = 5; \
> + do { \
> + _rval = qla2x00_start_sp(_sp); \
> + if (_rval == EAGAIN) \
> + msleep(1); \
> + else \
> + break; \
> + cnt--; \
> + } while (cnt); \
> +}
> +
> +static int
> +qla26xx_marker(struct tmf_arg *arg)
> +{
> + struct scsi_qla_host *vha = arg->vha;
> + struct srb_iocb *tm_iocb;
> + srb_t *sp;
> + int rval = QLA_FUNCTION_FAILED;
> + fc_port_t *fcport = arg->fcport;
> +
> + /* ref: INIT */
> + sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
> + if (!sp)
> + goto done;
> +
> + sp->type = SRB_MARKER;
> + sp->name = "marker";
> + qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha), qla_marker_sp_done);
> + sp->u.iocb_cmd.timeout = qla2x00_tmf_iocb_timeout;
> +
> + tm_iocb = &sp->u.iocb_cmd;
> + init_completion(&tm_iocb->u.tmf.comp);
> + tm_iocb->u.tmf.modifier = arg->modifier;
> + tm_iocb->u.tmf.lun = arg->lun;
> + tm_iocb->u.tmf.loop_id = fcport->loop_id;
> + tm_iocb->u.tmf.vp_index = vha->vp_idx;
> +
> + START_SP_W_RETRIES(sp, rval);
> +
> + 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",
> +    sp->handle, fcport->loop_id, fcport->d_id.b24,
> +    arg->modifier, arg->lun, sp->qpair->id, rval);
> +
> + if (rval != QLA_SUCCESS) {
> + ql_log(ql_log_warn, vha, 0x8031,
> +    "Marker IOCB failed (%x).\n", rval);
> + goto done_free_sp;
> + }
> +
> + wait_for_completion(&tm_iocb->u.tmf.comp);
> +
> +done_free_sp:
> + /* ref: INIT */
> + kref_put(&sp->cmd_kref, qla2x00_sp_release);
> +done:
> + return rval;
> +}
> +
> static void qla2x00_tmf_sp_done(srb_t *sp, int res)
> {
> struct srb_iocb *tmf = &sp->u.iocb_cmd;
> @@ -2026,7 +2100,6 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
> struct scsi_qla_host *vha = arg->vha;
> struct srb_iocb *tm_iocb;
> srb_t *sp;
> - unsigned long flags;
> int rval = QLA_FUNCTION_FAILED;
> 
> fc_port_t *fcport = arg->fcport;
> @@ -2048,11 +2121,12 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
> tm_iocb->u.tmf.flags = arg->flags;
> tm_iocb->u.tmf.lun = arg->lun;
> 
> - rval = qla2x00_start_sp(sp);
> + START_SP_W_RETRIES(sp, rval);
> +
> ql_dbg(ql_dbg_taskm, vha, 0x802f,
> -    "Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x ctrl=%x.\n",
> -    sp->handle, fcport->loop_id, fcport->d_id.b.domain,
> -    fcport->d_id.b.area, fcport->d_id.b.al_pa, arg->flags);
> +    "Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n",
> +    sp->handle, fcport->loop_id, fcport->d_id.b24,
> +    arg->flags, arg->lun, sp->qpair->id, rval);
> 
> if (rval != QLA_SUCCESS)
> goto done_free_sp;
> @@ -2065,17 +2139,8 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
>    "TM IOCB failed (%x).\n", rval);
> }
> 
> - if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
> - flags = tm_iocb->u.tmf.flags;
> - if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|
> - TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
> - flags = MK_SYNC_ID_LUN;
> - else
> - flags = MK_SYNC_ID;
> -
> - qla2x00_marker(vha, sp->qpair,
> -    sp->fcport->loop_id, arg->lun, flags);
> - }
> + if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw))
> + rval = qla26xx_marker(arg);
> 
> done_free_sp:
> /* ref: INIT */
> @@ -2099,6 +2164,11 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
> a.fcport = fcport;
> a.lun = lun;
> 
> + if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET| TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
> + a.modifier = MK_SYNC_ID_LUN;
> + else
> + a.modifier = MK_SYNC_ID;
> +
> if (vha->hw->mqenable) {
> for (i = 0; i < vha->hw->num_qpairs; i++) {
> qpair = vha->hw->queue_pair_map[i];
> diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
> index b02039601cc0..6acfdcc48b16 100644
> --- a/drivers/scsi/qla2xxx/qla_iocb.c
> +++ b/drivers/scsi/qla2xxx/qla_iocb.c
> @@ -522,21 +522,25 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
> return (QLA_FUNCTION_FAILED);
> }
> 
> + mrk24 = (struct mrk_entry_24xx *)mrk;
> +
> mrk->entry_type = MARKER_TYPE;
> mrk->modifier = type;
> if (type != MK_SYNC_ALL) {
> if (IS_FWI2_CAPABLE(ha)) {
> - mrk24 = (struct mrk_entry_24xx *) mrk;
> mrk24->nport_handle = cpu_to_le16(loop_id);
> int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
> host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
> mrk24->vp_index = vha->vp_idx;
> - mrk24->handle = make_handle(req->id, mrk24->handle);
> } else {
> SET_TARGET_ID(ha, mrk->target, loop_id);
> mrk->lun = cpu_to_le16((uint16_t)lun);
> }
> }
> +
> + if (IS_FWI2_CAPABLE(ha))
> + mrk24->handle = QLA_SKIP_HANDLE;
> +
> wmb();
> 
> qla2x00_start_iocbs(vha, req);
> @@ -3853,9 +3857,9 @@ static int qla_get_iocbs_resource(struct srb *sp)
> case SRB_NACK_LOGO:
> case SRB_LOGOUT_CMD:
> case SRB_CTRL_VP:
> - push_it_through = true;
> - fallthrough;
> + case SRB_MARKER:
> default:
> + push_it_through = true;
> get_exch = false;
> }
> 
> @@ -3871,6 +3875,19 @@ static int qla_get_iocbs_resource(struct srb *sp)
> return qla_get_fw_resources(sp->qpair, &sp->iores);
> }
> 
> +static void
> +qla_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk)
> +{
> + mrk->entry_type = MARKER_TYPE;
> + mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier;
> + if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) {
> + mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id);
> + int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun);
> + host_to_fcp_swap(mrk->lun, sizeof(mrk->lun));
> + mrk->vp_index = sp->u.iocb_cmd.u.tmf.vp_index;
> + }
> +}
> +
> int
> qla2x00_start_sp(srb_t *sp)
> {
> @@ -3974,6 +3991,9 @@ qla2x00_start_sp(srb_t *sp)
> case SRB_SA_REPLACE:
> qla24xx_sa_replace_iocb(sp, pkt);
> break;
> + case SRB_MARKER:
> + qla_marker_iocb(sp, pkt);
> + break;
> default:
> break;
> }
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
> index 71feda2cdb63..f3107508cf12 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -3750,6 +3750,28 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
> return rc;
> }
> 
> +static void qla_marker_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
> + struct mrk_entry_24xx *pkt)
> +{
> + const char func[] = "MRK-IOCB";
> + srb_t *sp;
> + int res = QLA_SUCCESS;
> +
> + if (!IS_FWI2_CAPABLE(vha->hw))
> + return;
> +
> + sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
> + if (!sp)
> + return;
> +
> + if (pkt->entry_status) {
> + ql_dbg(ql_dbg_taskm, vha, 0x8025, "marker failure.\n");
> + res = QLA_COMMAND_ERROR;
> + }
> + sp->u.iocb_cmd.u.tmf.data = res;
> + sp->done(sp, res);
> +}
> +
> /**
>  * qla24xx_process_response_queue() - Process response queue entries.
>  * @vha: SCSI driver HA context
> @@ -3863,9 +3885,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
> (struct nack_to_isp *)pkt);
> break;
> case MARKER_TYPE:
> - /* Do nothing in this case, this check is to prevent it
> - * from falling into default case
> - */
> + qla_marker_iocb_entry(vha, rsp->req, (struct mrk_entry_24xx *)pkt);
> break;
> case ABORT_IOCB_TYPE:
> qla24xx_abort_iocb_entry(vha, rsp->req,
> -- 
> 2.23.1
> 

Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx <mailto:himanshu.madhani@xxxxxxxxxx>>

-- 
Himanshu Madhani Oracle Linux Engineering





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux