> On Jul 12, 2023, at 2:05 AM, Nilesh Javali <njavali@xxxxxxxxxxx> wrote: > > From: Quinn Tran <qutran@xxxxxxxxxxx> > > During NVME queue creation, a new qpair is created, FW resource limit > need to be re-adjusted to take into account of the new qpair. Otherwise, > NVME command can not go through. > This issue was discovered while testing/forcing FW execution to fail at > load time. > > Add call to readjust iocb and exchange limit. > > In addition, get fw state command require FW to be running. Otherwise, > error is generated. > > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx> > Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx> > --- > drivers/scsi/qla2xxx/qla_gbl.h | 2 ++ > drivers/scsi/qla2xxx/qla_init.c | 52 +++++++++++++++++++++------------ > drivers/scsi/qla2xxx/qla_mbx.c | 3 ++ > drivers/scsi/qla2xxx/qla_nvme.c | 1 + > 4 files changed, 39 insertions(+), 19 deletions(-) > > diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h > index ba7831f24734..ec69b0e8f4c5 100644 > --- a/drivers/scsi/qla2xxx/qla_gbl.h > +++ b/drivers/scsi/qla2xxx/qla_gbl.h > @@ -143,6 +143,8 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess); > void qla_edif_clear_appdata(struct scsi_qla_host *vha, > struct fc_port *fcport); > const char *sc_to_str(uint16_t cmd); > +void qla_adjust_iocb_limit(scsi_qla_host_t *vha); > + > No need for extra line here > /* > * Global Data in qla_os.c source file. > diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c > index f8f64ed4de07..60dd0e415351 100644 > --- a/drivers/scsi/qla2xxx/qla_init.c > +++ b/drivers/scsi/qla2xxx/qla_init.c > @@ -4153,41 +4153,55 @@ qla24xx_detect_sfp(scsi_qla_host_t *vha) > return ha->flags.lr_detected; > } > > -void qla_init_iocb_limit(scsi_qla_host_t *vha) > +static void __qla_adjust_iocb_limit(struct qla_qpair *qpair) > { > - u16 i, num_qps; > - u32 limit; > - struct qla_hw_data *ha = vha->hw; > + u8 num_qps; > + u16 limit; > + struct qla_hw_data *ha = qpair->vha->hw; > > num_qps = ha->num_qpairs + 1; > limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; > > - ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; > - ha->base_qpair->fwres.iocbs_limit = limit; > - ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps; > - ha->base_qpair->fwres.iocbs_used = 0; > + qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; > + qpair->fwres.iocbs_limit = limit; > + qpair->fwres.iocbs_qp_limit = limit / num_qps; > + > + qpair->fwres.exch_total = ha->orig_fw_xcb_count; > + qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * > + QLA_IOCB_PCT_LIMIT) / 100; > +} > + > +void qla_init_iocb_limit(scsi_qla_host_t *vha) > +{ > + u8 i; > + struct qla_hw_data *ha = vha->hw; > > - ha->base_qpair->fwres.exch_total = ha->orig_fw_xcb_count; > - ha->base_qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * > - QLA_IOCB_PCT_LIMIT) / 100; > + __qla_adjust_iocb_limit(ha->base_qpair); > + ha->base_qpair->fwres.iocbs_used = 0; > ha->base_qpair->fwres.exch_used = 0; > > for (i = 0; i < ha->max_qpairs; i++) { > if (ha->queue_pair_map[i]) { > - ha->queue_pair_map[i]->fwres.iocbs_total = > - ha->orig_fw_iocb_count; > - ha->queue_pair_map[i]->fwres.iocbs_limit = limit; > - ha->queue_pair_map[i]->fwres.iocbs_qp_limit = > - limit / num_qps; > + __qla_adjust_iocb_limit(ha->queue_pair_map[i]); > ha->queue_pair_map[i]->fwres.iocbs_used = 0; > - ha->queue_pair_map[i]->fwres.exch_total = ha->orig_fw_xcb_count; > - ha->queue_pair_map[i]->fwres.exch_limit = > - (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100; > ha->queue_pair_map[i]->fwres.exch_used = 0; > } > } > } > > +void qla_adjust_iocb_limit(scsi_qla_host_t *vha) > +{ > + u8 i; > + struct qla_hw_data *ha = vha->hw; > + > + __qla_adjust_iocb_limit(ha->base_qpair); > + > + for (i = 0; i < ha->max_qpairs; i++) { > + if (ha->queue_pair_map[i]) > + __qla_adjust_iocb_limit(ha->queue_pair_map[i]); > + } > +} > + > /** > * qla2x00_setup_chip() - Load and start RISC firmware. > * @vha: HA context > diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c > index 254fd4c64262..b05f93037875 100644 > --- a/drivers/scsi/qla2xxx/qla_mbx.c > +++ b/drivers/scsi/qla2xxx/qla_mbx.c > @@ -2213,6 +2213,9 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) > ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, > "Entered %s.\n", __func__); > > + if (!ha->flags.fw_started) > + return QLA_FUNCTION_FAILED; > + > mcp->mb[0] = MBC_GET_FIRMWARE_STATE; > mcp->out_mb = MBX_0; > if (IS_FWI2_CAPABLE(vha->hw)) > diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c > index 86e85f2f4782..6769c40287b9 100644 > --- a/drivers/scsi/qla2xxx/qla_nvme.c > +++ b/drivers/scsi/qla2xxx/qla_nvme.c > @@ -132,6 +132,7 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, > "Failed to allocate qpair\n"); > return -EINVAL; > } > + qla_adjust_iocb_limit(vha); > } > *handle = qpair; > > -- > 2.23.1 > With the small nit fixed above you can add Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> -- Himanshu Madhani Oracle Linux Engineering