scsi: qla2xxx: Fix NVMe retry
authorQuinn Tran <qutran@marvell.com>
Tue, 17 Aug 2021 05:13:12 +0000 (22:13 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 24 Aug 2021 02:36:54 +0000 (22:36 -0400)
For target port that register itself as both FCP + NVMe, initiator driver
will try to login one mode at a time. If the last mode did not succeed,
then driver will try the other mode.

When error is encountered, current code only flip to other mode one time
(NVMe->FCP) and remain on the last mode.  Driver wrongly assumed target
port does not support PRLI NVMe, instead it was not ready to receive PRLI.

This patch will alternate back and forth on every PRLI failure until login
retry count has depleted or it is succeeded.

Link: https://lore.kernel.org/r/20210817051315.2477-10-njavali@marvell.com
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c

index cb5bf2585cb76d0f8aeb4a1631753bbfd65ae28d..be2eb75ee1a376d5d031affabd0bfb7fa902fc3b 100644 (file)
@@ -2517,6 +2517,8 @@ typedef struct fc_port {
        unsigned int n2n_flag:1;
        unsigned int explicit_logout:1;
        unsigned int prli_pend_timer:1;
+       unsigned int do_prli_nvme:1;
+
        uint8_t nvme_flag;
 
        uint8_t node_name[WWN_SIZE];
@@ -5351,9 +5353,12 @@ struct sff_8247_a0 {
 #define NVME_FCP_TARGET(fcport) \
        (FCP_TYPE(fcport) && NVME_TYPE(fcport)) \
 
+#define NVME_PRIORITY(ha, fcport) \
+       (NVME_FCP_TARGET(fcport) && \
+        (ha->fc4_type_priority == FC4_PRIORITY_NVME))
+
 #define NVME_TARGET(ha, fcport) \
-       ((NVME_FCP_TARGET(fcport) && \
-       (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
+       (fcport->do_prli_nvme || \
        NVME_ONLY_TARGET(fcport)) \
 
 #define PRLI_PHASE(_cls) \
index df6e3ef52e2c903334603389e3598edb873a3585..ebc8fdb0b43d3486c70c5b26f99366650c5019f0 100644 (file)
@@ -3504,6 +3504,14 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
                        fcport->last_rscn_gen = fcport->rscn_gen;
                        fcport->fc4_type = rp->fc4type;
                        found = true;
+
+                       if (fcport->scan_needed) {
+                               if (NVME_PRIORITY(vha->hw, fcport))
+                                       fcport->do_prli_nvme = 1;
+                               else
+                                       fcport->do_prli_nvme = 0;
+                       }
+
                        /*
                         * If device was not a fabric device before.
                         */
index 255f3a8884db196fe1159c1d82c5b088d881ae38..1e4e3e83b5c747bec8f2abea96e07f359f204ad2 100644 (file)
@@ -2000,6 +2000,7 @@ qla24xx_async_abort_command(srb_t *sp)
 static void
 qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 {
+       struct srb *sp;
        WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
                  ea->data[0]);
 
@@ -2027,22 +2028,27 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                        break;
                }
 
+               sp = ea->sp;
                ql_dbg(ql_dbg_disc, vha, 0x2118,
-                      "%s %d %8phC priority %s, fc4type %x\n",
+                      "%s %d %8phC priority %s, fc4type %x prev try %s\n",
                       __func__, __LINE__, ea->fcport->port_name,
                       vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
-                      "FCP" : "NVMe", ea->fcport->fc4_type);
+                      "FCP" : "NVMe", ea->fcport->fc4_type,
+                      (sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI) ?
+                       "NVME" : "FCP");
 
-               if (N2N_TOPO(vha->hw)) {
-                       if (vha->hw->fc4_type_priority == FC4_PRIORITY_FCP) {
-                               ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
-                               ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
-                       } else {
-                               ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
-                               ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
-                       }
+               if (NVME_FCP_TARGET(ea->fcport)) {
+                       if (sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI)
+                               ea->fcport->do_prli_nvme = 0;
+                       else
+                               ea->fcport->do_prli_nvme = 1;
+               } else {
+                       ea->fcport->do_prli_nvme = 0;
+               }
 
-                       if (ea->fcport->n2n_link_reset_cnt < 3) {
+               if (N2N_TOPO(vha->hw)) {
+                       if (ea->fcport->n2n_link_reset_cnt <
+                           vha->hw->login_retry_count) {
                                ea->fcport->n2n_link_reset_cnt++;
                                vha->relogin_jif = jiffies + 2 * HZ;
                                /*
@@ -2062,19 +2068,6 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                         * switch connect. login failed. Take connection down
                         * and allow relogin to retrigger
                         */
-                       if (NVME_FCP_TARGET(ea->fcport)) {
-                               ql_dbg(ql_dbg_disc, vha, 0x2118,
-                                      "%s %d %8phC post %s prli\n",
-                                      __func__, __LINE__,
-                                      ea->fcport->port_name,
-                                      (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
-                                      ? "NVMe" : "FCP");
-                               if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
-                                       ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
-                               else
-                                       ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
-                       }
-
                        ea->fcport->flags &= ~FCF_ASYNC_SENT;
                        ea->fcport->keep_nport_handle = 0;
                        ea->fcport->logout_on_delete = 1;
index fcc219172aa938c43ef04d4b1e5876f4dcad2c93..438af0d55135947de353c849f08fee3b118c76b7 100644 (file)
@@ -4050,6 +4050,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                                fcport->n2n_flag = 1;
                                fcport->keep_nport_handle = 1;
                                fcport->login_retry = vha->hw->login_retry_count;
+                               fcport->fc4_type = FS_FC4TYPE_FCP;
+                               if (vha->flags.nvme_enabled)
+                                       fcport->fc4_type |= FS_FC4TYPE_NVME;
 
                                if (wwn_to_u64(vha->port_name) >
                                    wwn_to_u64(fcport->port_name)) {
index bc8abe226fa6c86822b051b0cfcc765fe306422c..064dbbeda0ee630ab5cb8efefc204a57a1b85499 100644 (file)
@@ -5184,6 +5184,11 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                            WWN_SIZE);
 
                        fcport->fc4_type = e->u.new_sess.fc4_type;
+                       if (NVME_PRIORITY(vha->hw, fcport))
+                               fcport->do_prli_nvme = 1;
+                       else
+                               fcport->do_prli_nvme = 0;
+
                        if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
                                fcport->dm_login_expire = jiffies +
                                        QLA_N2N_WAIT_TIME * HZ;