]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: qla2xxx: Adjust IOCB resource on qpair create
authorQuinn Tran <qutran@marvell.com>
Fri, 14 Jul 2023 07:00:56 +0000 (12:30 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Sep 2023 10:27:55 +0000 (12:27 +0200)
commit efa74a62aaa2429c04fe6cb277b3bf6739747d86 upstream.

During NVMe queue creation, a new qpair is created. FW resource limit needs
to be re-adjusted to take into account 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 and 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>
Link: https://lore.kernel.org/r/20230714070104.40052-3-njavali@marvell.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_nvme.c

index 316122709b0e643f40dd57a4807278c7009d785b..2e4537f9e5b50ef52725120d5e78ffa5075380a4 100644 (file)
@@ -143,6 +143,7 @@ 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.
index 30bbf33e3a6aa997cb62cac1929bb5e38fb7f72e..a45d54963a86a22a5cf640730c5a31b612cb24c8 100644 (file)
@@ -4148,41 +4148,55 @@ out:
        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
index 359595a64664c3c5aefa3d74312213579a4efb21..3c2ee21195edb197d6f1bb2dd6cccfff65aa4bc2 100644 (file)
@@ -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))
index 57545d5e82b9d98bafea3e04fb82c0d480187eae..ebb8786c4c9962322f1d50688ec2047b9e90a921 100644 (file)
@@ -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;