From: Nigel Kirkland <nkirkland2304@gmail.com>
To: linux-scsi@vger.kernel.org, nigel.kirkland@broadcom.com
Cc: paul.ely@broadcom.com, nkirkland2304@gmail.com
Subject: [PATCH v5 09/10] lpfc: Update correct ndlp refcnt when rejecting an unsolicited PLOGI
Date: Mon, 28 Sep 2026 11:17:56 -0700 [thread overview]
Message-ID: <20260928181757.21959-10-nkirkland2304@gmail.com> (raw)
In-Reply-To: <20260928181757.21959-1-nkirkland2304@gmail.com>
The domain controller FC_ID can change whenever a fabric switch with
an ISL link is replaced or the admin reconfigures the fabric switch
with active links. In such situations, reference count updates should
be applied to the correct nodelist structure.
Signed-off-by: Nigel Kirkland <nkirkland2304@gmail.com>
---
drivers/scsi/lpfc/lpfc_els.c | 37 ++++++++++++++++++++++--------
drivers/scsi/lpfc/lpfc_hbadisc.c | 7 ++++++
drivers/scsi/lpfc/lpfc_nportdisc.c | 14 +++++++++++
3 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 1793d9c6d8b8..0ca1659d5d10 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -5977,11 +5977,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
/* Xmit ELS RJT <err> response tag <ulpIoTag> */
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"0129 Xmit ELS RJT x%x response tag x%x "
- "xri x%x, did x%x, nlp_flag x%lx, nlp_state x%x, "
- "rpi x%x\n",
+ "xri x%x, ndlp x%px, did x%x, nlp_flag x%lx, "
+ "nlp_state x%x, rpi x%x ref_cnt %d\n",
rejectError, elsiocb->iotag,
- get_job_ulpcontext(phba, elsiocb), ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
+ get_job_ulpcontext(phba, elsiocb), ndlp,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi, kref_read(&ndlp->kref));
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
"Issue LS_RJT: did:x%x flg:x%lx err:x%x",
ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
@@ -10482,6 +10483,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
{
struct lpfc_nodelist *ndlp;
+ struct lpfc_nodelist *alloc_ndlp = NULL;
struct ls_rjt stat;
u32 *payload, payload_len;
u32 cmd = 0, did = 0, newnode, status = 0;
@@ -10580,7 +10582,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
did, vport->port_state, ndlp->nlp_flag);
phba->fc_stat.elsRcvPLOGI++;
+ alloc_ndlp = ndlp;
ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
+
if (phba->sli_rev == LPFC_SLI_REV4 &&
test_bit(FC_PT2PT, &phba->pport->fc_flag)) {
vport->fc_prevDID = vport->fc_myDID;
@@ -10896,13 +10900,28 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
stat.un.b.lsRjtRsnCodeExp = rjt_exp;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
NULL);
- /* Remove the reference from above for new nodes. */
- if (newnode)
- lpfc_disc_state_machine(vport, ndlp, NULL,
- NLP_EVT_DEVICE_RM);
+
+ /* Remove the safety reference from routine start. */
+ if (newnode) {
+ /* alloc_ndlp is assigned for an unsolicited PLOGI from
+ * the ndlp allocated by this routine. The routine
+ * lpfc_plogi_confirm_nport may have swapped the initial
+ * ndlp to an existing ndlp. In that case, alloc_ndlp
+ * is the pre-swap ndlp that needs a DEVICE_RM because
+ * it is the newnode. For all other paths to lsrjt
+ * (non-PLOGI ELS) that were rejected by the early
+ * port_state check, alloc_ndlp is NULL and ndlp is
+ * still the originally allocated node.
+ */
+ lpfc_disc_state_machine(vport,
+ alloc_ndlp ? alloc_ndlp : ndlp,
+ NULL, NLP_EVT_DEVICE_RM);
+ }
}
- /* Release the reference on this elsiocb, not the ndlp. */
+ /* This elsiocb is not the IOCB issued for a response. Remove
+ * the safety reference allocated earlier.
+ */
lpfc_nlp_put(elsiocb->ndlp);
elsiocb->ndlp = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 83e29eed14fa..6665c3e5b62d 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -4978,6 +4978,13 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
*/
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
return;
+
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_ELS | LOG_DISCOVERY,
+ "3421 Mark ndlp x%px Dropped. DID x%06x, nflags x%lx "
+ "xflags x%x ref_cnt %d\n",
+ ndlp, ndlp->nlp_DID, ndlp->nlp_flag,
+ ndlp->fc4_xpt_flags, kref_read(&ndlp->kref));
+
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
lpfc_cleanup_vports_rrqs(vport, ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index f917a5bcfd02..ffec352c8ab2 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -2878,6 +2878,20 @@ lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
set_bit(NLP_NODEV_REMOVE, &ndlp->nlp_flag);
return ndlp->nlp_state;
}
+
+ /* It is an error to drop a node while either of its transport
+ * registrations have not completed.
+ */
+ if (ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) {
+ lpfc_printf_vlog(vport, KERN_WARNING,
+ LOG_ELS | LOG_NODE | LOG_DISCOVERY,
+ "3423 Not dropping ndlp x%px, DID x%x xflags x%x "
+ "with dev_loss pending. ref_cnt %d\n",
+ ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags,
+ kref_read(&ndlp->kref));
+ return ndlp->nlp_state;
+ }
+
lpfc_drop_node(vport, ndlp);
return NLP_STE_FREED_NODE;
}
--
2.38.0
next prev parent reply other threads:[~2026-09-28 17:55 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 18:17 [PATCH v5 00/10] lpfc: Update lpfc to revision 15.0.0.1 Nigel Kirkland
2026-09-28 18:17 ` [PATCH v5 01/10] lpfc: Fix use-after-free in lpfc_cmpl_ct_cmd_vmid Nigel Kirkland
2026-09-28 18:17 ` [PATCH v5 02/10] lpfc: Early return out of lpfc_els_abort when HBA_SETUP flag is not set Nigel Kirkland
2026-09-28 18:17 ` [PATCH v5 03/10] lpfc: Fix kernel oops when unmapping scsi dma buffers for an aborted cmd Nigel Kirkland
2026-09-28 18:17 ` [PATCH v5 04/10] lpfc: Check fc4_xpt_flags before decrementing ndlp kref on FDISC error Nigel Kirkland
2026-09-28 18:19 ` sashiko-bot
2026-09-28 18:17 ` [PATCH v5 05/10] lpfc: Add handling for when PLOGI or PRLI is dropped during link failure Nigel Kirkland
2026-09-28 18:17 ` sashiko-bot
2026-09-28 18:17 ` [PATCH v5 06/10] lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence Nigel Kirkland
2026-09-28 18:09 ` sashiko-bot
2026-09-28 18:17 ` [PATCH v5 07/10] lpfc: Rework I/O flush ordering when unloading driver Nigel Kirkland
2026-09-28 18:18 ` sashiko-bot
2026-09-28 18:17 ` [PATCH v5 08/10] lpfc: Refactor calls on fc_disctmo to lpfc_set_disctmo in RSCN handler Nigel Kirkland
2026-09-28 18:17 ` Nigel Kirkland [this message]
2026-09-28 18:14 ` [PATCH v5 09/10] lpfc: Update correct ndlp refcnt when rejecting an unsolicited PLOGI sashiko-bot
2026-09-28 18:17 ` [PATCH v5 10/10] lpfc: Update lpfc version to 15.0.0.1 Nigel Kirkland
2026-10-01 18:12 ` [PATCH v5 00/10] lpfc: Update lpfc to revision 15.0.0.1 Nigel Kirkland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260928181757.21959-10-nkirkland2304@gmail.com \
--to=nkirkland2304@gmail.com \
--cc=linux-scsi@vger.kernel.org \
--cc=nigel.kirkland@broadcom.com \
--cc=paul.ely@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox