]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: lpfc: fcoe: Fix link down issue after 1000+ link bounces
authorJames Smart <jsmart2021@gmail.com>
Tue, 23 Oct 2018 20:41:06 +0000 (13:41 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Nov 2019 17:26:06 +0000 (18:26 +0100)
[ Upstream commit 036cad1f1ac9ce03e2db94b8460f98eaf1e1ee4c ]

On FCoE adapters, when running link bounce test in a loop, initiator
failed to login with switch switch and required driver reload to
recover. Switch reached a point where all subsequent FLOGIs would be
LS_RJT'd. Further testing showed the condition to be related to not
performing FCF discovery between FLOGI's.

Fix by monitoring FLOGI failures and once a repeated error is seen
repeat FCF discovery.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli4.h

index 82a690924f5ebc86b08ab2ffd0e5546abe90c4e4..7ca8c2522c9288795b902ff7f870fd2c31f568d7 100644 (file)
@@ -1124,6 +1124,7 @@ stop_rr_fcf_flogi:
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
                        phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
+                       phba->fcf.fcf_redisc_attempted = 0; /* reset */
                        goto out;
                }
                if (!rc) {
@@ -1138,6 +1139,7 @@ stop_rr_fcf_flogi:
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
                        phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
+                       phba->fcf.fcf_redisc_attempted = 0; /* reset */
                        goto out;
                }
        }
index a67950908db17c78bf0f2484d5102803e414296f..d50db2004d21e2e900c9288367387fd2e60c245b 100644 (file)
@@ -1966,6 +1966,26 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *vport, uint16_t fcf_index)
                                "failover and change port state:x%x/x%x\n",
                                phba->pport->port_state, LPFC_VPORT_UNKNOWN);
                phba->pport->port_state = LPFC_VPORT_UNKNOWN;
+
+               if (!phba->fcf.fcf_redisc_attempted) {
+                       lpfc_unregister_fcf(phba);
+
+                       rc = lpfc_sli4_redisc_fcf_table(phba);
+                       if (!rc) {
+                               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                               "3195 Rediscover FCF table\n");
+                               phba->fcf.fcf_redisc_attempted = 1;
+                               lpfc_sli4_clear_fcf_rr_bmask(phba);
+                       } else {
+                               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                                               "3196 Rediscover FCF table "
+                                               "failed. Status:x%x\n", rc);
+                       }
+               } else {
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                                       "3197 Already rediscover FCF table "
+                                       "attempted. No more retry\n");
+               }
                goto stop_flogi_current_fcf;
        } else {
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_ELS,
index 60c21093f86565fc07fe4cd0c52dc910cea94802..7e06fd6127ccb529582068088516af196218b0dd 100644 (file)
@@ -4376,7 +4376,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
                        break;
                }
                /* If fast FCF failover rescan event is pending, do nothing */
-               if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
+               if (phba->fcf.fcf_flag & (FCF_REDISC_EVT | FCF_REDISC_PEND)) {
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }
index ad4f16ab7f7a2f7e801f98b22d98998592e207ac..523a1058078a534df4bde7a4bbec2c790247ca78 100644 (file)
@@ -16350,15 +16350,8 @@ next_priority:
                        goto initial_priority;
                lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
                                "2844 No roundrobin failover FCF available\n");
-               if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
-                       return LPFC_FCOE_FCF_NEXT_NONE;
-               else {
-                       lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
-                               "3063 Only FCF available idx %d, flag %x\n",
-                               next_fcf_index,
-                       phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag);
-                       return next_fcf_index;
-               }
+
+               return LPFC_FCOE_FCF_NEXT_NONE;
        }
 
        if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX &&
index 1e916e16ce989beb47b4c3d13db70619407047aa..0ecf92c8a28824c0cf024b665dd4d9f541d2fdab 100644 (file)
@@ -237,6 +237,7 @@ struct lpfc_fcf {
 #define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
 #define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
 #define FCF_REDISC_PROG (FCF_REDISC_PEND | FCF_REDISC_EVT)
+       uint16_t fcf_redisc_attempted;
        uint32_t addr_mode;
        uint32_t eligible_fcf_cnt;
        struct lpfc_fcf_rec current_rec;