Message ID | 20230428075339.32551-4-njavali@marvell.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | qla2xxx driver update | expand |
> On Apr 28, 2023, at 12:53 AM, Nilesh Javali <njavali@marvell.com> wrote: > > From: Quinn Tran <qutran@marvell.com> > > Task management command failed with status 2Ch which is > a result of too many task management commands sent > to the same target. Hence limit task management commands > to 8 per target. > > Reported-by: kernel test robot <lkp@intel.com> > Link: https://lore.kernel.org/oe-kbuild-all/202304271952.NKNmoFzv-lkp@intel.com/ > Cc: stable@vger.kernel.org > Signed-off-by: Quinn Tran <qutran@marvell.com> > Signed-off-by: Nilesh Javali <njavali@marvell.com> > --- > v2: > - Fix warning reported by kernel robot. > > drivers/scsi/qla2xxx/qla_def.h | 3 ++ > drivers/scsi/qla2xxx/qla_init.c | 63 ++++++++++++++++++++++++++++++--- > 2 files changed, 61 insertions(+), 5 deletions(-) > > diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h > index 0437e0150a50..0971150953a9 100644 > --- a/drivers/scsi/qla2xxx/qla_def.h > +++ b/drivers/scsi/qla2xxx/qla_def.h > @@ -2543,6 +2543,7 @@ enum rscn_addr_format { > typedef struct fc_port { > struct list_head list; > struct scsi_qla_host *vha; > + struct list_head tmf_pending; > > unsigned int conf_compl_supported:1; > unsigned int deleted:2; > @@ -2563,6 +2564,8 @@ typedef struct fc_port { > unsigned int do_prli_nvme:1; > > uint8_t nvme_flag; > + uint8_t active_tmf; > +#define MAX_ACTIVE_TMF 8 > > uint8_t node_name[WWN_SIZE]; > uint8_t port_name[WWN_SIZE]; > diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c > index 2402b1402e0d..17649cf9c39d 100644 > --- a/drivers/scsi/qla2xxx/qla_init.c > +++ b/drivers/scsi/qla2xxx/qla_init.c > @@ -2149,6 +2149,54 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) > return rval; > } > > +static void qla_put_tmf(fc_port_t *fcport) > +{ > + struct scsi_qla_host *vha = fcport->vha; > + struct qla_hw_data *ha = vha->hw; > + unsigned long flags; > + > + spin_lock_irqsave(&ha->tgt.sess_lock, flags); > + fcport->active_tmf--; > + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); > +} > + > +static > +int qla_get_tmf(fc_port_t *fcport) > +{ > + struct scsi_qla_host *vha = fcport->vha; > + struct qla_hw_data *ha = vha->hw; > + unsigned long flags; > + int rc = 0; > + LIST_HEAD(tmf_elem); > + > + spin_lock_irqsave(&ha->tgt.sess_lock, flags); > + list_add_tail(&tmf_elem, &fcport->tmf_pending); > + > + while (fcport->active_tmf >= MAX_ACTIVE_TMF) { > + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); > + > + msleep(1); > + > + spin_lock_irqsave(&ha->tgt.sess_lock, flags); > + if (fcport->deleted) { > + rc = EIO; > + break; > + } > + if (fcport->active_tmf < MAX_ACTIVE_TMF && > + list_is_first(&tmf_elem, &fcport->tmf_pending)) > + break; > + } > + > + list_del(&tmf_elem); > + > + if (!rc) > + fcport->active_tmf++; > + > + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); > + > + return rc; > +} > + > int > qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, > uint32_t tag) > @@ -2156,18 +2204,19 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, > struct scsi_qla_host *vha = fcport->vha; > struct qla_qpair *qpair; > struct tmf_arg a; > - struct completion comp; > int i, rval; > > - init_completion(&comp); > a.vha = fcport->vha; > a.fcport = fcport; > a.lun = lun; > - > - if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET| TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) > + if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET| TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) { > a.modifier = MK_SYNC_ID_LUN; > - else > + > + if (qla_get_tmf(fcport)) > + return QLA_FUNCTION_FAILED; > + } else { > a.modifier = MK_SYNC_ID; > + } > > if (vha->hw->mqenable) { > for (i = 0; i < vha->hw->num_qpairs; i++) { > @@ -2186,6 +2235,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, > a.flags = flags; > rval = __qla2x00_async_tm_cmd(&a); > > + if (a.modifier == MK_SYNC_ID_LUN) > + qla_put_tmf(fcport); > + > return rval; > } > > @@ -5400,6 +5452,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) > INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); > INIT_LIST_HEAD(&fcport->gnl_entry); > INIT_LIST_HEAD(&fcport->list); > + INIT_LIST_HEAD(&fcport->tmf_pending); > > INIT_LIST_HEAD(&fcport->sess_cmd_list); > spin_lock_init(&fcport->sess_cmd_lock); > -- > 2.23.1 > Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0437e0150a50..0971150953a9 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2543,6 +2543,7 @@ enum rscn_addr_format { typedef struct fc_port { struct list_head list; struct scsi_qla_host *vha; + struct list_head tmf_pending; unsigned int conf_compl_supported:1; unsigned int deleted:2; @@ -2563,6 +2564,8 @@ typedef struct fc_port { unsigned int do_prli_nvme:1; uint8_t nvme_flag; + uint8_t active_tmf; +#define MAX_ACTIVE_TMF 8 uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 2402b1402e0d..17649cf9c39d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2149,6 +2149,54 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) return rval; } +static void qla_put_tmf(fc_port_t *fcport) +{ + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + unsigned long flags; + + spin_lock_irqsave(&ha->tgt.sess_lock, flags); + fcport->active_tmf--; + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); +} + +static +int qla_get_tmf(fc_port_t *fcport) +{ + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + unsigned long flags; + int rc = 0; + LIST_HEAD(tmf_elem); + + spin_lock_irqsave(&ha->tgt.sess_lock, flags); + list_add_tail(&tmf_elem, &fcport->tmf_pending); + + while (fcport->active_tmf >= MAX_ACTIVE_TMF) { + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); + + msleep(1); + + spin_lock_irqsave(&ha->tgt.sess_lock, flags); + if (fcport->deleted) { + rc = EIO; + break; + } + if (fcport->active_tmf < MAX_ACTIVE_TMF && + list_is_first(&tmf_elem, &fcport->tmf_pending)) + break; + } + + list_del(&tmf_elem); + + if (!rc) + fcport->active_tmf++; + + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); + + return rc; +} + int qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, uint32_t tag) @@ -2156,18 +2204,19 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, struct scsi_qla_host *vha = fcport->vha; struct qla_qpair *qpair; struct tmf_arg a; - struct completion comp; int i, rval; - init_completion(&comp); a.vha = fcport->vha; a.fcport = fcport; a.lun = lun; - - if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET| TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) + if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET| TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) { a.modifier = MK_SYNC_ID_LUN; - else + + if (qla_get_tmf(fcport)) + return QLA_FUNCTION_FAILED; + } else { a.modifier = MK_SYNC_ID; + } if (vha->hw->mqenable) { for (i = 0; i < vha->hw->num_qpairs; i++) { @@ -2186,6 +2235,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, a.flags = flags; rval = __qla2x00_async_tm_cmd(&a); + if (a.modifier == MK_SYNC_ID_LUN) + qla_put_tmf(fcport); + return rval; } @@ -5400,6 +5452,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); + INIT_LIST_HEAD(&fcport->tmf_pending); INIT_LIST_HEAD(&fcport->sess_cmd_list); spin_lock_init(&fcport->sess_cmd_lock);