diff mbox series

[02/10] qla2xxx: Adjust iocb resource on qpair create

Message ID 20230712090535.34894-3-njavali@marvell.com
State Superseded
Headers show
Series qla2xxx driver bug fixes | expand

Commit Message

Nilesh Javali July 12, 2023, 9:05 a.m. UTC
From: Quinn Tran <qutran@marvell.com>

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@vger.kernel.org
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
---
 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(-)

Comments

Himanshu Madhani July 13, 2023, 6:45 p.m. UTC | #1
> On Jul 12, 2023, at 2:05 AM, Nilesh Javali <njavali@marvell.com> wrote:
> 
> From: Quinn Tran <qutran@marvell.com>
> 
> 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@vger.kernel.org
> Signed-off-by: Quinn Tran <qutran@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> ---
> 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@oracle.com>
diff mbox series

Patch

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);
+
 
 /*
  * 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;