All of lore.kernel.org
 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.12 19/36] scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback
Date: Wed,  4 Dec 2024 10:45:35 -0500	[thread overview]
Message-ID: <20241204154626.2211476-19-sashal@kernel.org> (raw)
In-Reply-To: <20241204154626.2211476-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 9241075f72fa4..6e8d8a96c54fb 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 16:58 UTC|newest]

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