diff options
author | Justin Tee <justin.tee@broadcom.com> | 2025-04-25 12:48:02 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2025-04-28 21:38:14 -0400 |
commit | df117c93f58ab93c71413496491fdf543dbd7eca (patch) | |
tree | 1502d94eac88ca3899f36e4a6ce358d70ad13b7d | |
parent | 19d768dca549d492fcf222f50067752e80062bc0 (diff) |
scsi: lpfc: Prevent failure to reregister with NVMe transport after PRLI retry
A failure to unregister with the NVMe transport may occur when a PRLI is
retried.
Remove duplicate testing of NLP_NVME_TARGET flag. Add a secondary check
of the registered state based on the nrport information. Further qualify
the ndlp reference count modification when nvme_fc_register_remoteport()
returns an error.
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20250425194806.3585-5-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nvme.c | 8 |
2 files changed, 7 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index b5273cb1adbd..9e585af05bec 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4695,9 +4695,7 @@ lpfc_nlp_unreg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) if (ndlp->fc4_xpt_flags & NVME_XPT_REGD) { vport->phba->nport_event_cnt++; if (vport->phba->nvmet_support == 0) { - /* Start devloss if target. */ - if (ndlp->nlp_type & NLP_NVME_TARGET) - lpfc_nvme_unregister_port(vport, ndlp); + lpfc_nvme_unregister_port(vport, ndlp); } else { /* NVMET has no upcall. */ lpfc_nlp_put(ndlp); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index b1adb9f59097..9d61e1251a2f 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2508,7 +2508,10 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) "6031 RemotePort Registration failed " "err: %d, DID x%06x ref %u\n", ret, ndlp->nlp_DID, kref_read(&ndlp->kref)); - lpfc_nlp_put(ndlp); + + /* Only release reference if one was taken for this request */ + if (!oldrport) + lpfc_nlp_put(ndlp); } return ret; @@ -2614,7 +2617,8 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * clear any rport state until the transport calls back. */ - if (ndlp->nlp_type & NLP_NVME_TARGET) { + if ((ndlp->nlp_type & NLP_NVME_TARGET) || + (remoteport->port_role & FC_PORT_ROLE_NVME_TARGET)) { /* No concern about the role change on the nvme remoteport. * The transport will update it. */ |