scsi: lpfc: Call discovery state machine when handling PLOGI/ADISC completions
authorJames Smart <jsmart2021@gmail.com>
Wed, 7 Jul 2021 18:43:47 +0000 (11:43 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 19 Jul 2021 02:30:37 +0000 (22:30 -0400)
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>
drivers/scsi/lpfc/lpfc_els.c

index 32f5f00..11e5653 100644 (file)
@@ -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,12 +2752,9 @@ 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);
+
+               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
@@ -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);