From: sashiko-bot@kernel.org
To: "Justin Tee" <justintee8345@gmail.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v3 08/14] lpfc: Improve PLOGI retry handling for large SAN configurations
Date: Tue, 14 Jul 2026 00:55:02 +0000 [thread overview]
Message-ID: <20260714005503.5B96E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260714011812.106753-9-justintee8345@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] Non-atomic test-and-set and post-submission setting of NLP_PLOGI_SND causes permanent target block or bypassed serialization.
- [High] New state validation check in `lpfc_issue_els_plogi` silently drops legitimate PLOGIs, stalling discovery.
- [High] TOCTOU race in delayed PLOGI timer and unreg completion permanently drops deferred PLOGIs.
- [Medium] The `NLP_PLOGI_SND` flag is completely bypassed when a PLOGI IOCB is queued for retry upon `IOCB_FAILED_PUT`.
--
--- Patch [8]: [PATCH v3 08/14] lpfc: Improve PLOGI retry handling for large SAN configurations ---
commit 1ce21a9bd9de0c81a785643032705d301dd6dccb
Author: Justin Tee <justintee8345@gmail.com>
Date: Tue Jul 14 01:18:06 2026 +0000
lpfc: Improve PLOGI retry handling for large SAN configurations
In large SAN configurations with link perturbations, rediscovery of target
ports is problematic due to PLOGI retry race conditions.
This patch improves target rediscovery by ensuring PLOGI retries are
serialized in unregistration and retry handler paths.
> diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
> index 6720fd5ec5232..16b10377a0953 100644
> --- a/drivers/scsi/lpfc/lpfc_els.c
> +++ b/drivers/scsi/lpfc/lpfc_els.c
[ ... ]
> @@ -2329,17 +2331,43 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
[ ... ]
> + if (test_bit(NLP_PLOGI_SND, &ndlp->nlp_flag)) {
[Severity: Critical]
Can NLP_PLOGI_SND become permanently stuck?
The flag is tested here, but it is not set until after the I/O is submitted
to the HBA at the end of the function. If the hardware completes the PLOGI
quickly, the completion handler lpfc_cmpl_els_plogi() might run before the
issuing thread sets the bit.
The completion handler would clear the bit, achieving nothing, and then the
issuing thread would execute set_bit(), leaving the flag permanently set.
Could this permanently reject future PLOGIs? Would test_and_set_bit() be
more appropriate here to prevent this regression?
> + lpfc_printf_vlog(vport, KERN_INFO,
> + LOG_ELS | LOG_NODE | LOG_DISCOVERY,
> + "4113 Reject PLOGI issue, PLOGI in-flight "
> + "x%px, DID x%x nflag x%lx\n",
> + ndlp, ndlp->nlp_DID, ndlp->nlp_flag);
> + return 1;
> + }
> +
> + if (ndlp->nlp_state > NLP_STE_PLOGI_ISSUE &&
> + ndlp->nlp_state <= NLP_STE_MAPPED_NODE) {
[Severity: High]
Does this block legitimate PLOGIs during discovery?
For example, lpfc_rcv_plogi_adisc_issue() calls lpfc_issue_els_plogi() while
the node is in NLP_STE_ADISC_ISSUE. The PLOGI would be silently rejected
here, but the caller proceeds to force the state to NLP_STE_PLOGI_ISSUE
anyway.
Could this cause the port state machine to wait forever for a PLOGI
completion that will never arrive?
> + lpfc_printf_vlog(vport, KERN_INFO,
> + LOG_ELS | LOG_NODE | LOG_DISCOVERY,
> + "4114 Reject PLOGI issue, Node in "
> + "unexpected state x%px, DID x%x nflag x%lx "
> + "in State x%x\n",
> + ndlp, ndlp->nlp_DID,
> + ndlp->nlp_flag, ndlp->nlp_state);
> + return 1;
> }
>
> cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
> @@ -2415,6 +2443,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
[ ... ]
> /* Under heavy vpi counts, the driver's host_index can catch up
> * to the hba_index causing a put error. Catch this case and
> * put the IO on phba->txq.
> */
> if (ret == IOCB_FAILED_PUT && phba->sli_rev == LPFC_SLI_REV4) {
> lpfc_sli4_queue_io_for_retry(phba, elsiocb, false);
> return 0;
> }
[Severity: Medium]
If the IO is queued for retry here and returns early, doesn't it bypass
setting NLP_PLOGI_SND at the bottom of this function?
Since the IO is queued but the flag isn't set, wouldn't concurrent callers
pass the test_bit() check and issue duplicate PLOGIs, bypassing the
intended serialization?
> lpfc_els_free_iocb(phba, elsiocb);
> lpfc_nlp_put(ndlp);
> return 1;
> }
>
> + set_bit(NLP_PLOGI_SND, &ndlp->nlp_flag);
> return 0;
> }
>
> @@ -4614,6 +4643,31 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
[ ... ]
> case ELS_CMD_PLOGI:
> + /* The driver delayed a PLOGI via the nlp_delayfunc, but
> + * it's possible the PLOGI is already on a deferred retry.
> + * Catch this case and skip this delayed PLOGI. This prevents
> + * multiple PLOGIs in flight. The defer code flow cleans
> + * up.
> + */
> + if ((test_bit(NLP_IGNR_REG_CMPL, &ndlp->nlp_flag) ||
> + test_bit(NLP_UNREG_INP, &ndlp->nlp_flag)) &&
[Severity: High]
Is there a race condition here with the unreg completion interrupt?
In lpfc_els_retry_delay_handler(), nlp_last_elscmd is temporarily cleared
before reaching this point. If this timer thread decides to skip issuing the
PLOGI because NLP_UNREG_INP is set:
CPU1 (lpfc_els_retry_delay_handler)
cmd = ndlp->nlp_last_elscmd;
ndlp->nlp_last_elscmd = 0;
...
if (... test_bit(NLP_UNREG_INP, &ndlp->nlp_flag) ...) {
If CPU2 processes the unreg completion interrupt at this exact moment:
CPU2 (lpfc_sli4_unreg_rpi_cmpl_clr)
if (!test_bit(NLP_DELAY_TMO, &ndlp->nlp_flag) &&
ndlp->nlp_last_elscmd == ELS_CMD_PLOGI) {
CPU2 will see nlp_last_elscmd as 0 and skip issuing the PLOGI.
Then CPU1 resumes:
CPU1
ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
break;
Could this result in both paths skipping the PLOGI, permanently stalling
recovery?
> + ndlp->nlp_defer_did != NLP_EVT_NOTHING_PENDING &&
> + ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
> + !test_bit(FC_OFFLINE_MODE, &vport->fc_flag)) {
> + /* When UNREG_RPI completes we need to have the
> + * nlp_last_elscmd set.
> + */
> + ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714011812.106753-1-justintee8345@gmail.com?part=8
next prev parent reply other threads:[~2026-07-14 0:55 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 1:17 [PATCH v3 00/14] Update lpfc to revision 15.0.0.1 Justin Tee
2026-07-14 1:17 ` [PATCH v3 01/14] lpfc: Fix use-after-free in lpfc_cmpl_ct_cmd_vmid Justin Tee
2026-07-14 0:51 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 02/14] lpfc: Early return out of lpfc_els_abort when HBA_SETUP flag is not set Justin Tee
2026-07-14 0:53 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 03/14] lpfc: Fix kernel oops when unmapping scsi dma buffers for an aborted cmd Justin Tee
2026-07-14 0:57 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 04/14] lpfc: Check fc4_xpt_flags before decrementing ndlp kref on FDISC error Justin Tee
2026-07-14 0:55 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 05/14] lpfc: Add handling for when PLOGI or PRLI is dropped during link failure Justin Tee
2026-07-14 1:02 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 06/14] lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence Justin Tee
2026-07-14 0:50 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 07/14] lpfc: Rework I/O flush ordering when unloading driver Justin Tee
2026-07-14 1:00 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 08/14] lpfc: Improve PLOGI retry handling for large SAN configurations Justin Tee
2026-07-14 0:55 ` sashiko-bot [this message]
2026-07-14 1:18 ` [PATCH v3 09/14] lpfc: Send inhibited ABORT_WQE when PLOGI CQE SEQUENCE_TMO is received Justin Tee
2026-07-14 1:05 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 10/14] lpfc: Remove slowpath cqe process limiter in slow ring event handler Justin Tee
2026-07-14 0:54 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 11/14] lpfc: Put iocbq on phba->txq when ELS WQ is full or ELS SGL unavailable Justin Tee
2026-07-14 0:50 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 12/14] lpfc: Update ELS ACC logging for diagnostic troubleshooting Justin Tee
2026-07-14 1:02 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 13/14] lpfc: Refactor calls on fc_disctmo to lpfc_set_disctmo in RSCN handler Justin Tee
2026-07-14 1:00 ` sashiko-bot
2026-07-14 1:18 ` [PATCH v3 14/14] lpfc: Update lpfc version to 15.0.0.1 Justin Tee
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=20260714005503.5B96E1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=justintee8345@gmail.com \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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