Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05678af0 authored by James Smart's avatar James Smart Committed by Greg Kroah-Hartman
Browse files

scsi: lpfc: fcoe: Fix link down issue after 1000+ link bounces



[ 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: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent e6d0262e
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -1157,6 +1157,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
			phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
			phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
			phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
			spin_unlock_irq(&phba->hbalock);
			spin_unlock_irq(&phba->hbalock);
			phba->fcf.fcf_redisc_attempted = 0; /* reset */
			goto out;
			goto out;
		}
		}
		if (!rc) {
		if (!rc) {
@@ -1171,6 +1172,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
			phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
			phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
			phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
			spin_unlock_irq(&phba->hbalock);
			spin_unlock_irq(&phba->hbalock);
			phba->fcf.fcf_redisc_attempted = 0; /* reset */
			goto out;
			goto out;
		}
		}
	}
	}
+20 −0
Original line number Original line Diff line number Diff line
@@ -1997,6 +1997,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",
				"failover and change port state:x%x/x%x\n",
				phba->pport->port_state, LPFC_VPORT_UNKNOWN);
				phba->pport->port_state, LPFC_VPORT_UNKNOWN);
		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;
		goto stop_flogi_current_fcf;
	} else {
	} else {
		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_ELS,
		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_ELS,
+1 −1
Original line number Original line Diff line number Diff line
@@ -5044,7 +5044,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
			break;
			break;
		}
		}
		/* If fast FCF failover rescan event is pending, do nothing */
		/* 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);
			spin_unlock_irq(&phba->hbalock);
			break;
			break;
		}
		}
+2 −9
Original line number Original line Diff line number Diff line
@@ -18431,15 +18431,8 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
			goto initial_priority;
			goto initial_priority;
		lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
		lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
				"2844 No roundrobin failover FCF available\n");
				"2844 No roundrobin failover FCF available\n");
		if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
		return LPFC_FCOE_FCF_NEXT_NONE;
		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;
		}
	}
	}
	if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX &&
	if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX &&
+1 −0
Original line number Original line Diff line number Diff line
@@ -279,6 +279,7 @@ struct lpfc_fcf {
#define FCF_REDISC_EVT	0x100 /* FCF rediscovery event to worker thread */
#define FCF_REDISC_EVT	0x100 /* FCF rediscovery event to worker thread */
#define FCF_REDISC_FOV	0x200 /* Post FCF rediscovery fast failover */
#define FCF_REDISC_FOV	0x200 /* Post FCF rediscovery fast failover */
#define FCF_REDISC_PROG (FCF_REDISC_PEND | FCF_REDISC_EVT)
#define FCF_REDISC_PROG (FCF_REDISC_PEND | FCF_REDISC_EVT)
	uint16_t fcf_redisc_attempted;
	uint32_t addr_mode;
	uint32_t addr_mode;
	uint32_t eligible_fcf_cnt;
	uint32_t eligible_fcf_cnt;
	struct lpfc_fcf_rec current_rec;
	struct lpfc_fcf_rec current_rec;