]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: lpfc: Fix handling of fully recovered fabric node in dev_loss callbk
authorJustin Tee <justin.tee@broadcom.com>
Fri, 28 Jun 2024 17:20:07 +0000 (10:20 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 5 Jul 2024 03:24:51 +0000 (23:24 -0400)
In rare cases when a fabric node is recovered after a link bounce and
before dev_loss_tmo callbk is reached, the driver may leave the fabric node
in an inconsistent state with the NLP_IN_DEV_LOSS flag perpetually set.

In lpfc_dev_loss_tmo_callbk, a check is added for a recovered fabric node.
If the node is recovered, then don't queue the lpfc_dev_loss_tmo_handler
work. In lpfc_dev_loss_tmo_handler, the path taken for the recovered fabric
nodes is updated to clear the NLP_IN_DEV_LOSS flag.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240628172011.25921-5-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_hbadisc.c

index 13b08c85440fec5beae218c479aeb9b33edaa3f7..6943f6c6395c41bbbc68c203a3e601da6ff6fd3f 100644 (file)
@@ -214,6 +214,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
        if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
                return;
 
+       /* check for recovered fabric node */
+       if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
+           ndlp->nlp_DID == Fabric_DID)
+               return;
+
        if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn))
                lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
                                 "6789 rport name %llx != node port name %llx",
@@ -546,6 +551,9 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                                         ndlp->nlp_DID, kref_read(&ndlp->kref),
                                         ndlp, ndlp->nlp_flag,
                                         vport->port_state);
+                       spin_lock_irqsave(&ndlp->lock, iflags);
+                       ndlp->nlp_flag &= ~NLP_IN_DEV_LOSS;
+                       spin_unlock_irqrestore(&ndlp->lock, iflags);
                        return fcf_inuse;
                }