]> 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:22:54 +0000 (12:22 +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 9e467262c0f17ec65196d3db2396c91291f88f62..3861e41a8d2cde047930fcd69ae9a33c52004083 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 b86dba4b128e5fdfd63603bdfbb67ed8cd568762..672406c85fb13b234d7d16d7fbdeb42887c3bf24 100644 (file)
@@ -4149,41 +4149,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 5bcb8da4360f2d0e6a4562da7b7ee9f0d7f05824..cacf28a3e6406bf38194d154e54328afcb7d398a 100644 (file)
@@ -2207,6 +2207,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 53a54e8a4d97f26d1b8bcac011725028a2119863..1e27208899ef6d711dc7f87a14683d05e8dffc09 100644 (file)
@@ -127,6 +127,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;