mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Justin Tee <justin.tee@broadcom.com>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	Sasha Levin <sashal@kernel.org>,
	james.smart@broadcom.com, dick.kennedy@broadcom.com,
	James.Bottomley@HansenPartnership.com,
	linux-scsi@vger.kernel.org
Subject: [PATCH AUTOSEL 6.11 18/33] scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback
Date: Wed,  4 Dec 2024 10:47:31 -0500	[thread overview]
Message-ID: <20241204154817.2212455-18-sashal@kernel.org> (raw)
In-Reply-To: <20241204154817.2212455-1-sashal@kernel.org>

From: Justin Tee <justin.tee@broadcom.com>

[ Upstream commit 4281f44ea8bfedd25938a0031bebba1473ece9ad ]

Current dev_loss_tmo handling checks whether there has been a previous
call to unregister with SCSI transport.  If so, the NDLP kref count is
decremented a second time in dev_loss_tmo as the final kref release.
However, this can sometimes result in a reference count underflow if
there is also a race to unregister with NVMe transport as well.  Add a
check for NVMe transport registration before decrementing the final
kref.  If NVMe transport is still registered, then the NVMe transport
unregistration is designated as the final kref decrement.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20241031223219.152342-8-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/lpfc/lpfc_hbadisc.c | 36 +++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 35c9181c6608a..bc19b060bac3c 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -155,6 +155,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 	struct lpfc_hba   *phba;
 	struct lpfc_work_evt *evtp;
 	unsigned long iflags;
+	bool nvme_reg = false;
 
 	ndlp = ((struct lpfc_rport_data *)rport->dd_data)->pnode;
 	if (!ndlp)
@@ -177,38 +178,49 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 	/* Don't schedule a worker thread event if the vport is going down. */
 	if (test_bit(FC_UNLOADING, &vport->load_flag) ||
 	    !test_bit(HBA_SETUP, &phba->hba_flag)) {
+
 		spin_lock_irqsave(&ndlp->lock, iflags);
 		ndlp->rport = NULL;
 
+		if (ndlp->fc4_xpt_flags & NVME_XPT_REGD)
+			nvme_reg = true;
+
 		/* The scsi_transport is done with the rport so lpfc cannot
-		 * call to unregister. Remove the scsi transport reference
-		 * and clean up the SCSI transport node details.
+		 * call to unregister.
 		 */
-		if (ndlp->fc4_xpt_flags & (NLP_XPT_REGD | SCSI_XPT_REGD)) {
+		if (ndlp->fc4_xpt_flags & SCSI_XPT_REGD) {
 			ndlp->fc4_xpt_flags &= ~SCSI_XPT_REGD;
 
-			/* NVME transport-registered rports need the
-			 * NLP_XPT_REGD flag to complete an unregister.
+			/* If NLP_XPT_REGD was cleared in lpfc_nlp_unreg_node,
+			 * unregister calls were made to the scsi and nvme
+			 * transports and refcnt was already decremented. Clear
+			 * the NLP_XPT_REGD flag only if the NVME Rport is
+			 * confirmed unregistered.
 			 */
-			if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
+			if (!nvme_reg && ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
 				ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
+				spin_unlock_irqrestore(&ndlp->lock, iflags);
+				lpfc_nlp_put(ndlp); /* may free ndlp */
+			} else {
+				spin_unlock_irqrestore(&ndlp->lock, iflags);
+			}
+		} else {
 			spin_unlock_irqrestore(&ndlp->lock, iflags);
-			lpfc_nlp_put(ndlp);
-			spin_lock_irqsave(&ndlp->lock, iflags);
 		}
 
+		spin_lock_irqsave(&ndlp->lock, iflags);
+
 		/* Only 1 thread can drop the initial node reference.  If
 		 * another thread has set NLP_DROPPED, this thread is done.
 		 */
-		if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD) &&
-		    !(ndlp->nlp_flag & NLP_DROPPED)) {
-			ndlp->nlp_flag |= NLP_DROPPED;
+		if (nvme_reg || (ndlp->nlp_flag & NLP_DROPPED)) {
 			spin_unlock_irqrestore(&ndlp->lock, iflags);
-			lpfc_nlp_put(ndlp);
 			return;
 		}
 
+		ndlp->nlp_flag |= NLP_DROPPED;
 		spin_unlock_irqrestore(&ndlp->lock, iflags);
+		lpfc_nlp_put(ndlp);
 		return;
 	}
 
-- 
2.43.0


  parent reply	other threads:[~2024-12-04 17:00 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-04 15:47 [PATCH AUTOSEL 6.11 01/33] pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 02/33] rtla: Fix consistency in getopt_long for timerlat_hist Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 03/33] tracing/ftrace: disable preemption in syscall probe Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 04/33] tracing: Use atomic64_inc_return() in trace_clock_counter() Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 05/33] tools/rtla: fix collision with glibc sched_attr/sched_set_attr Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 06/33] rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 07/33] rtla/timerlat: Make timerlat_hist_cpu->*_count " Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 08/33] scsi: hisi_sas: Add cond_resched() for no forced preemption model Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 09/33] scsi: hisi_sas: Create all dump files during debugfs initialization Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 10/33] rtla/utils: Add idle state disabling via libcpupower Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 11/33] ring-buffer: Limit time with disabled interrupts in rb_check_pages() Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 12/33] pinmux: Use sequential access to access desc->pinmux data Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 13/33] scsi: ufs: core: Make DMA mask configuration more flexible Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 14/33] mfd: axp20x: Allow multiple regulators Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 15/33] bpf: put bpf_link's program when link is safe to be deallocated Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 16/33] scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 17/33] scsi: lpfc: Check SLI_ACTIVE flag in FDMI cmpl before submitting follow up FDMI Sasha Levin
2024-12-04 15:47 ` Sasha Levin [this message]
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 19/33] clk: qcom: rcg2: add clk_rcg2_shared_floor_ops Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 20/33] clk: qcom: rpmh: add support for SAR2130P Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 21/33] clk: qcom: tcsrcc-sm8550: add SAR2130P support Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 22/33] clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574 Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 23/33] leds: class: Protect brightness_show() with led_cdev->led_access mutex Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 24/33] scsi: st: Don't modify unknown block number in MTIOCGET Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 25/33] scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 26/33] pinctrl: qcom-pmic-gpio: add support for PM8937 Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 27/33] pinctrl: qcom: spmi-mpp: Add PM8937 compatible Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 28/33] thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 29/33] nvdimm: rectify the illogical code within nd_dax_probe() Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 30/33] smb: client: memcpy() with surrounding object base address Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 31/33] tools/rtla: Enhance argument parsing in timerlat_load.py Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 32/33] verification/dot2: Improve dot parser robustness Sasha Levin
2024-12-04 15:47 ` [PATCH AUTOSEL 6.11 33/33] mailbox: pcc: Check before sending MCTP PCC response ACK Sasha Levin

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=20241204154817.2212455-18-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=dick.kennedy@broadcom.com \
    --cc=james.smart@broadcom.com \
    --cc=justin.tee@broadcom.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=stable@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®