Blob Blame History Raw
From: James Smart <jsmart2021@gmail.com>
Date: Wed, 7 Jul 2021 11:43:47 -0700
Subject: scsi: lpfc: Call discovery state machine when handling PLOGI/ADISC
 completions
Patch-mainline: v5.15-rc1
Git-commit: c65436b21c3abbdaacd9c9f68bf2fa94e103168d
References: bsc#1189385

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: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Daniel Wagner <dwagner@suse.de>
---
 drivers/scsi/lpfc/lpfc_els.c |   15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2007,9 +2007,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phb
 				 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);
 
@@ -2045,7 +2043,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phb
 					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);
@@ -2706,12 +2703,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phb
 				 "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);
+
+		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
+				NLP_EVT_CMPL_ADISC);
 
 		/* As long as this node is not registered with the SCSI or NVMe
 		 * transport, it is no longer an active node. Otherwise
@@ -2729,7 +2723,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phb
 		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);