Commit 796876fd authored by Justin Tee's avatar Justin Tee Committed by Martin K. Petersen
Browse files

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: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230301231626.9621-9-justintee8345@gmail.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 27c2bcf0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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 "
+7 −7
Original line number Diff line number Diff line
@@ -1088,7 +1088,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			}

			/* 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 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	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;
+35 −0
Original line number Diff line number Diff line
@@ -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;
}
+0 −12
Original line number Diff line number Diff line
@@ -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 */