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

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.comCo-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
...@@ -2031,9 +2031,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2031,9 +2031,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
irsp->un.ulpWord[4]); irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp)) if (!lpfc_error_lost_link(irsp))
goto check_plogi;
else
lpfc_disc_state_machine(vport, ndlp, cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_PLOGI); NLP_EVT_CMPL_PLOGI);
...@@ -2086,7 +2084,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2086,7 +2084,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
NLP_EVT_CMPL_PLOGI); NLP_EVT_CMPL_PLOGI);
} }
check_plogi:
if (disc && vport->num_disc_nodes) { if (disc && vport->num_disc_nodes) {
/* Check to see if there are more PLOGIs to be sent */ /* Check to see if there are more PLOGIs to be sent */
lpfc_more_plogi(vport); lpfc_more_plogi(vport);
...@@ -2755,10 +2752,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -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", "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
ndlp->nlp_DID, irsp->ulpStatus, ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4]); 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, lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_ADISC); NLP_EVT_CMPL_ADISC);
...@@ -2778,7 +2772,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2778,7 +2772,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_disc_state_machine(vport, ndlp, cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_ADISC); NLP_EVT_CMPL_ADISC);
check_adisc:
/* Check to see if there are more ADISCs to be sent */ /* Check to see if there are more ADISCs to be sent */
if (disc && vport->num_disc_nodes) if (disc && vport->num_disc_nodes)
lpfc_more_adisc(vport); lpfc_more_adisc(vport);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment