Commit 036cad1f authored by James Smart's avatar James Smart Committed by Martin K. Petersen

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

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>
parent 191e2f74
...@@ -1157,6 +1157,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -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, ...@@ -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;
} }
} }
......
...@@ -1992,6 +1992,26 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *vport, uint16_t fcf_index) ...@@ -1992,6 +1992,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,
......
...@@ -5069,7 +5069,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, ...@@ -5069,7 +5069,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;
} }
......
...@@ -18712,15 +18712,8 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba) ...@@ -18712,15 +18712,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 &&
......
...@@ -279,6 +279,7 @@ struct lpfc_fcf { ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment