scsi: lpfc: Revise lpfc_error_lost_link() reason code evaluation logic

Extended status reason code errors should mask off the IOERR_PARAM_MASK
before checking strict equalities for IOERR values.

Update the lpfc_error_lost_link() routine as such.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230301231626.9621-9-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Justin Tee 2023-03-01 15:16:24 -08:00 коммит произвёл Martin K. Petersen
Родитель 27c2bcf00a
Коммит 796876fdae
5 изменённых файлов: 46 добавлений и 21 удалений

Просмотреть файл

@ -458,6 +458,8 @@ void lpfc_get_cfgparam(struct lpfc_hba *);
void lpfc_get_vport_cfgparam(struct lpfc_vport *);
int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
void lpfc_free_sysfs_attr(struct lpfc_vport *);
bool lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status,
u32 ulp_word4);
extern const struct attribute_group *lpfc_hba_groups[];
extern const struct attribute_group *lpfc_vport_groups[];
extern struct scsi_host_template lpfc_template;

Просмотреть файл

@ -958,7 +958,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto out;
}
if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0226 NS query failed due to link event: "
"ulp_status x%x ulp_word4 x%x fc_flag x%x "
@ -1181,7 +1181,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto out;
}
if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"4166 NS query failed due to link event: "
"ulp_status x%x ulp_word4 x%x fc_flag x%x "

Просмотреть файл

@ -1088,7 +1088,7 @@ stop_rr_fcf_flogi:
}
/* Do not register VFI if the driver aborted FLOGI */
if (!lpfc_error_lost_link(ulp_status, ulp_word4))
if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4))
lpfc_issue_reg_vfi(vport);
lpfc_nlp_put(ndlp);
@ -1207,7 +1207,7 @@ flogifail:
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
if (!lpfc_error_lost_link(ulp_status, ulp_word4)) {
if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {
/* FLOGI failed, so just use loop map to make discovery list */
lpfc_disc_list_loopmap(vport);
@ -2087,7 +2087,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
ulp_word4);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (!lpfc_error_lost_link(ulp_status, ulp_word4))
if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4))
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_PLOGI);
@ -2383,7 +2383,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
ndlp->fc4_prli_sent);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (!lpfc_error_lost_link(ulp_status, ulp_word4))
if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4))
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_PRLI);
@ -3038,7 +3038,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
ndlp->nlp_DID, ulp_status,
ulp_word4);
if (lpfc_error_lost_link(ulp_status, ulp_word4))
if (lpfc_error_lost_link(vport, ulp_status, ulp_word4))
skip_recovery = 1;
}
@ -4930,7 +4930,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if ((cmd == ELS_CMD_FLOGI) &&
(phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
!lpfc_error_lost_link(ulp_status, ulp_word4)) {
!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {
/* FLOGI retry policy */
retry = 1;
/* retry FLOGI forever */
@ -4944,7 +4944,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
else if (cmdiocb->retry >= 32)
delay = 1000;
} else if ((cmd == ELS_CMD_FDISC) &&
!lpfc_error_lost_link(ulp_status, ulp_word4)) {
!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {
/* retry FDISCs every second up to devloss */
retry = 1;
maxretry = vport->cfg_devloss_tmo;

Просмотреть файл

@ -7269,3 +7269,38 @@ lpfc_parse_fcoe_conf(struct lpfc_hba *phba,
lpfc_read_fcf_conn_tbl(phba, rec_ptr);
}
/*
* lpfc_error_lost_link - IO failure from link event or FW reset check.
*
* @vport: Pointer to lpfc_vport data structure.
* @ulp_status: IO completion status.
* @ulp_word4: Reason code for the ulp_status.
*
* This function evaluates the ulp_status and ulp_word4 values
* for specific error values that indicate an internal link fault
* or fw reset event for the completing IO. Callers require this
* common data to decide next steps on the IO.
*
* Return:
* false - No link or reset error occurred.
* true - A link or reset error occurred.
*/
bool
lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status, u32 ulp_word4)
{
/* Mask off the extra port data to get just the reason code. */
u32 rsn_code = IOERR_PARAM_MASK & ulp_word4;
if (ulp_status == IOSTAT_LOCAL_REJECT &&
(rsn_code == IOERR_SLI_ABORTED ||
rsn_code == IOERR_LINK_DOWN ||
rsn_code == IOERR_SLI_DOWN)) {
lpfc_printf_vlog(vport, KERN_WARNING, LOG_SLI | LOG_ELS,
"0408 Report link error true: <x%x:x%x>\n",
ulp_status, ulp_word4);
return true;
}
return false;
}

Просмотреть файл

@ -4435,16 +4435,4 @@ lpfc_is_LC_HBA(unsigned short device)
return 0;
}
/*
* Determine if failed because of a link event or firmware reset.
*/
static inline int
lpfc_error_lost_link(u32 ulp_status, u32 ulp_word4)
{
return (ulp_status == IOSTAT_LOCAL_REJECT &&
(ulp_word4 == IOERR_SLI_ABORTED ||
ulp_word4 == IOERR_LINK_DOWN ||
ulp_word4 == IOERR_SLI_DOWN));
}
#define BPL_ALIGN_SZ 8 /* 8 byte alignment for bpl and mbufs */