scsi: lpfc: Fix pt2pt state transition causing rmmod hang
authorJames Smart <jsmart2021@gmail.com>
Mon, 1 Mar 2021 17:18:15 +0000 (09:18 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 4 Mar 2021 22:37:05 +0000 (17:37 -0500)
On a setup with a dual port HBA and both ports direct connected, an rmmod
hangs momentarily when we log an Illegal State Transition. Once it resumes,
a nodelist not empty logic is hit, which forces rmmod to cleanup and exit.
We're missing a state transition case in the discovery engine.

Fix by adding a case for a DEVICE_RM event while in the unmapped state to
avoid illegal state transition log message.

Link: https://lore.kernel.org/r/20210301171821.3427-17-jsmart2021@gmail.com
Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_nportdisc.c

index 090a4232bfa81a9eb759cc02f8d8fd228de49c4c..e178ffb4e4ebe419d2ee8aa1717823d694d4638b 100644 (file)
@@ -2485,6 +2485,16 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        return ndlp->nlp_state;
 }
 
+static uint32_t
+lpfc_device_rm_unmap_node(struct lpfc_vport *vport,
+                         struct lpfc_nodelist *ndlp,
+                         void *arg,
+                         uint32_t evt)
+{
+       lpfc_drop_node(vport, ndlp);
+       return NLP_STE_FREED_NODE;
+}
+
 static uint32_t
 lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
                             struct lpfc_nodelist *ndlp,
@@ -2978,7 +2988,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
        lpfc_disc_illegal,              /* CMPL_LOGO       */
        lpfc_disc_illegal,              /* CMPL_ADISC      */
        lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
-       lpfc_disc_illegal,              /* DEVICE_RM       */
+       lpfc_device_rm_unmap_node,      /* DEVICE_RM       */
        lpfc_device_recov_unmap_node,   /* DEVICE_RECOVERY */
 
        lpfc_rcv_plogi_mapped_node,     /* RCV_PLOGI   MAPPED_NODE    */