Commit c65436b2 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Call discovery state machine when handling PLOGI/ADISC completions

In the PLOGI and ADISC completion handling, the device removal event could
be skipped during some link errors. This could leave a stale node in UNUSED
state.  Driver unload would hang for a long time waiting for this node to
be freed.

Resolve by taking the following steps:

 - Always post ADISC completion events to discovery state machine upon
   ADISC completion.

 - In case of a completion error for PLOGI/ADISC, ensure that init refcount
   is dropped if not registered with transport.

Link: https://lore.kernel.org/r/20210707184351.67872-17-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 06145683
Loading
Loading
Loading
Loading
+4 −11
Original line number Diff line number Diff line
@@ -2031,9 +2031,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
				 irsp->un.ulpWord[4]);

		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
		if (lpfc_error_lost_link(irsp))
			goto check_plogi;
		else
		if (!lpfc_error_lost_link(irsp))
			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
						NLP_EVT_CMPL_PLOGI);

@@ -2086,7 +2084,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
					NLP_EVT_CMPL_PLOGI);
	}

 check_plogi:
	if (disc && vport->num_disc_nodes) {
		/* Check to see if there are more PLOGIs to be sent */
		lpfc_more_plogi(vport);
@@ -2755,10 +2752,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
				 "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
				 ndlp->nlp_DID, irsp->ulpStatus,
				 irsp->un.ulpWord[4]);
		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
		if (lpfc_error_lost_link(irsp))
			goto check_adisc;
		else

		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
				NLP_EVT_CMPL_ADISC);

@@ -2778,7 +2772,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
					NLP_EVT_CMPL_ADISC);

 check_adisc:
	/* Check to see if there are more ADISCs to be sent */
	if (disc && vport->num_disc_nodes)
		lpfc_more_adisc(vport);