linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] nvme-fc: misc small improvents
@ 2025-10-30 10:05 Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 1/5] nvme-fc: don't hold rport lock when putting ctrl Daniel Wagner
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

Updated the first patch to use the safe iterator variant as suggested by Justin.

orig cover text:

I've collected a bunch of patches from the last debugging session. I think it's
worth documenting which conditions are expected in the cleanup path by adding a
bunch of WARNs.

Also found a deadlock in the nvme-fc code, so this one should definitly go in.

Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
Changes in v2:
- use safe iterator variant in first patch
- added missing signed off tag
- collected reviewed tags
- Link to v1: https://patch.msgid.link/20251028-nvmet-fcloop-fixes-v1-0-765427148613@kernel.org

---
Daniel Wagner (5):
      nvme-fc: don't hold rport lock when putting ctrl
      nvme-fc: check all request and response have been processed
      nvmet-fcloop: check all request and response have been processed
      nvmet-fcloop: remove unused lsdir member.
      nvmet-fc: use pr_* print macros instead of dev_*

 drivers/nvme/host/fc.c       |  8 ++++++--
 drivers/nvme/target/fc.c     | 48 +++++++++++++++++++-------------------------
 drivers/nvme/target/fcloop.c |  9 ++++++---
 3 files changed, 33 insertions(+), 32 deletions(-)
---
base-commit: 77a4fe6a06e265bd94d2b3cdc87fb3cde877a05b
change-id: 20251028-nvmet-fcloop-fixes-4e57e82f1f15

Best regards,
-- 
Daniel Wagner <wagi@kernel.org>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/5] nvme-fc: don't hold rport lock when putting ctrl
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
@ 2025-10-30 10:05 ` Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 2/5] nvme-fc: check all request and response have been processed Daniel Wagner
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

nvme_fc_ctrl_put can acquire the rport lock when freeing the
ctrl object:

nvme_fc_ctrl_put
  nvme_fc_ctrl_free
    spin_lock_irqsave(rport->lock)

Thus we can't hold the rport lock when calling nvme_fc_ctrl_put.

Justin suggested use the safe list iterator variant because
nvme_fc_ctrl_put will also modify the rport->list.

Cc: Justin Tee <justin.tee@broadcom.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
 drivers/nvme/host/fc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 03987f497a5b..3ff70e6e8131 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1468,14 +1468,14 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport,
 {
 	struct fcnvme_ls_disconnect_assoc_rqst *rqst =
 					&lsop->rqstbuf->rq_dis_assoc;
-	struct nvme_fc_ctrl *ctrl, *ret = NULL;
+	struct nvme_fc_ctrl *ctrl, *tmp, *ret = NULL;
 	struct nvmefc_ls_rcv_op *oldls = NULL;
 	u64 association_id = be64_to_cpu(rqst->associd.association_id);
 	unsigned long flags;
 
 	spin_lock_irqsave(&rport->lock, flags);
 
-	list_for_each_entry(ctrl, &rport->ctrl_list, ctrl_list) {
+	list_for_each_entry_safe(ctrl, tmp, &rport->ctrl_list, ctrl_list) {
 		if (!nvme_fc_ctrl_get(ctrl))
 			continue;
 		spin_lock(&ctrl->lock);
@@ -1488,7 +1488,9 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport,
 		if (ret)
 			/* leave the ctrl get reference */
 			break;
+		spin_unlock_irqrestore(&rport->lock, flags);
 		nvme_fc_ctrl_put(ctrl);
+		spin_lock_irqsave(&rport->lock, flags);
 	}
 
 	spin_unlock_irqrestore(&rport->lock, flags);

-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/5] nvme-fc: check all request and response have been processed
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 1/5] nvme-fc: don't hold rport lock when putting ctrl Daniel Wagner
@ 2025-10-30 10:05 ` Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 3/5] nvmet-fcloop: " Daniel Wagner
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

When the rport is removed there shouldn't be any in flight request or
responses.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
 drivers/nvme/host/fc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 3ff70e6e8131..b613fc5966a7 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -520,6 +520,8 @@ nvme_fc_free_rport(struct kref *ref)
 
 	WARN_ON(rport->remoteport.port_state != FC_OBJSTATE_DELETED);
 	WARN_ON(!list_empty(&rport->ctrl_list));
+	WARN_ON(!list_empty(&rport->ls_req_list));
+	WARN_ON(!list_empty(&rport->ls_rcv_list));
 
 	/* remove from lport list */
 	spin_lock_irqsave(&nvme_fc_lock, flags);

-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/5] nvmet-fcloop: check all request and response have been processed
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 1/5] nvme-fc: don't hold rport lock when putting ctrl Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 2/5] nvme-fc: check all request and response have been processed Daniel Wagner
@ 2025-10-30 10:05 ` Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 4/5] nvmet-fcloop: remove unused lsdir member Daniel Wagner
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

When the remoteport or the targetport are removed check that there are
no inflight requests or responses.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
 drivers/nvme/target/fcloop.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index 5dffcc5becae..4e429a1ea2bd 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -1111,8 +1111,10 @@ fcloop_remoteport_delete(struct nvme_fc_remote_port *remoteport)
 	rport->nport->rport = NULL;
 	spin_unlock_irqrestore(&fcloop_lock, flags);
 
-	if (put_port)
+	if (put_port) {
+		WARN_ON(!list_empty(&rport->ls_list));
 		fcloop_nport_put(rport->nport);
+	}
 }
 
 static void
@@ -1130,8 +1132,10 @@ fcloop_targetport_delete(struct nvmet_fc_target_port *targetport)
 	tport->nport->tport = NULL;
 	spin_unlock_irqrestore(&fcloop_lock, flags);
 
-	if (put_port)
+	if (put_port) {
+		WARN_ON(!list_empty(&tport->ls_list));
 		fcloop_nport_put(tport->nport);
+	}
 }
 
 #define	FCLOOP_HW_QUEUES		4

-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/5] nvmet-fcloop: remove unused lsdir member.
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
                   ` (2 preceding siblings ...)
  2025-10-30 10:05 ` [PATCH v2 3/5] nvmet-fcloop: " Daniel Wagner
@ 2025-10-30 10:05 ` Daniel Wagner
  2025-10-30 10:05 ` [PATCH v2 5/5] nvmet-fc: use pr_* print macros instead of dev_* Daniel Wagner
  2025-10-30 21:44 ` [PATCH v2 0/5] nvme-fc: misc small improvents Keith Busch
  5 siblings, 0 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

Nothing is using lsdir member in struct fcloop_lsreq.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
 drivers/nvme/target/fcloop.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index 4e429a1ea2bd..c30e9a3e014f 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -254,7 +254,6 @@ struct fcloop_nport {
 struct fcloop_lsreq {
 	struct nvmefc_ls_req		*lsreq;
 	struct nvmefc_ls_rsp		ls_rsp;
-	int				lsdir;	/* H2T or T2H */
 	int				status;
 	struct list_head		ls_list; /* fcloop_rport->ls_list */
 };

-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/5] nvmet-fc: use pr_* print macros instead of dev_*
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
                   ` (3 preceding siblings ...)
  2025-10-30 10:05 ` [PATCH v2 4/5] nvmet-fcloop: remove unused lsdir member Daniel Wagner
@ 2025-10-30 10:05 ` Daniel Wagner
  2025-10-30 21:44 ` [PATCH v2 0/5] nvme-fc: misc small improvents Keith Busch
  5 siblings, 0 replies; 7+ messages in thread
From: Daniel Wagner @ 2025-10-30 10:05 UTC (permalink / raw)
  To: Justin Tee, Christoph Hellwig, Keith Busch
  Cc: James Smart, Jens Axboe, linux-nvme, linux-kernel, Daniel Wagner

Many of the nvmet-fc log messages cannot print the device used, because
it's not there yet:

  (NULL device *): {0:0} Association deleted

Use the pr_* macros consistently throughout the module and match the
output of the nvme-fc module.

Using port:association ids are more useful when debugging what's going
on, because these match now with the log entries from nvme-fc.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <wagi@kernel.org>
---
 drivers/nvme/target/fc.c | 48 +++++++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 7d84527d5a43..0d9784004c9b 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -490,8 +490,7 @@ nvmet_fc_xmt_disconnect_assoc(struct nvmet_fc_tgt_assoc *assoc)
 			sizeof(*discon_rqst) + sizeof(*discon_acc) +
 			tgtport->ops->lsrqst_priv_sz), GFP_KERNEL);
 	if (!lsop) {
-		dev_info(tgtport->dev,
-			"{%d:%d} send Disconnect Association failed: ENOMEM\n",
+		pr_info("{%d:%d}: send Disconnect Association failed: ENOMEM\n",
 			tgtport->fc_target_port.port_num, assoc->a_id);
 		return;
 	}
@@ -513,8 +512,7 @@ nvmet_fc_xmt_disconnect_assoc(struct nvmet_fc_tgt_assoc *assoc)
 	ret = nvmet_fc_send_ls_req_async(tgtport, lsop,
 				nvmet_fc_disconnect_assoc_done);
 	if (ret) {
-		dev_info(tgtport->dev,
-			"{%d:%d} XMT Disconnect Association failed: %d\n",
+		pr_info("{%d:%d}: XMT Disconnect Association failed: %d\n",
 			tgtport->fc_target_port.port_num, assoc->a_id, ret);
 		kfree(lsop);
 	}
@@ -1187,8 +1185,7 @@ nvmet_fc_target_assoc_free(struct kref *ref)
 	if (oldls)
 		nvmet_fc_xmt_ls_rsp(tgtport, oldls);
 	ida_free(&tgtport->assoc_cnt, assoc->a_id);
-	dev_info(tgtport->dev,
-		"{%d:%d} Association freed\n",
+	pr_info("{%d:%d}: Association freed\n",
 		tgtport->fc_target_port.port_num, assoc->a_id);
 	kfree(assoc);
 }
@@ -1224,8 +1221,7 @@ nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc)
 			flush_workqueue(assoc->queues[i]->work_q);
 	}
 
-	dev_info(tgtport->dev,
-		"{%d:%d} Association deleted\n",
+	pr_info("{%d:%d}: Association deleted\n",
 		tgtport->fc_target_port.port_num, assoc->a_id);
 
 	nvmet_fc_tgtport_put(tgtport);
@@ -1716,9 +1712,9 @@ nvmet_fc_ls_create_association(struct nvmet_fc_tgtport *tgtport,
 	}
 
 	if (ret) {
-		dev_err(tgtport->dev,
-			"Create Association LS failed: %s\n",
-			validation_errors[ret]);
+		pr_err("{%d}: Create Association LS failed: %s\n",
+		       tgtport->fc_target_port.port_num,
+		       validation_errors[ret]);
 		iod->lsrsp->rsplen = nvme_fc_format_rjt(acc,
 				sizeof(*acc), rqst->w0.ls_cmd,
 				FCNVME_RJT_RC_LOGIC,
@@ -1730,8 +1726,7 @@ nvmet_fc_ls_create_association(struct nvmet_fc_tgtport *tgtport,
 	atomic_set(&queue->connected, 1);
 	queue->sqhd = 0;	/* best place to init value */
 
-	dev_info(tgtport->dev,
-		"{%d:%d} Association created\n",
+	pr_info("{%d:%d}: Association created\n",
 		tgtport->fc_target_port.port_num, iod->assoc->a_id);
 
 	/* format a response */
@@ -1809,9 +1804,9 @@ nvmet_fc_ls_create_connection(struct nvmet_fc_tgtport *tgtport,
 	}
 
 	if (ret) {
-		dev_err(tgtport->dev,
-			"Create Connection LS failed: %s\n",
-			validation_errors[ret]);
+		pr_err("{%d}: Create Connection LS failed: %s\n",
+		       tgtport->fc_target_port.port_num,
+		       validation_errors[ret]);
 		iod->lsrsp->rsplen = nvme_fc_format_rjt(acc,
 				sizeof(*acc), rqst->w0.ls_cmd,
 				(ret == VERR_NO_ASSOC) ?
@@ -1871,9 +1866,9 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
 	}
 
 	if (ret || !assoc) {
-		dev_err(tgtport->dev,
-			"Disconnect LS failed: %s\n",
-			validation_errors[ret]);
+		pr_err("{%d}: Disconnect LS failed: %s\n",
+		       tgtport->fc_target_port.port_num,
+		       validation_errors[ret]);
 		iod->lsrsp->rsplen = nvme_fc_format_rjt(acc,
 				sizeof(*acc), rqst->w0.ls_cmd,
 				(ret == VERR_NO_ASSOC) ?
@@ -1907,8 +1902,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
 	spin_unlock_irqrestore(&tgtport->lock, flags);
 
 	if (oldls) {
-		dev_info(tgtport->dev,
-			"{%d:%d} Multiple Disconnect Association LS's "
+		pr_info("{%d:%d}: Multiple Disconnect Association LS's "
 			"received\n",
 			tgtport->fc_target_port.port_num, assoc->a_id);
 		/* overwrite good response with bogus failure */
@@ -2051,8 +2045,8 @@ nvmet_fc_rcv_ls_req(struct nvmet_fc_target_port *target_port,
 	struct fcnvme_ls_rqst_w0 *w0 = (struct fcnvme_ls_rqst_w0 *)lsreqbuf;
 
 	if (lsreqbuf_len > sizeof(union nvmefc_ls_requests)) {
-		dev_info(tgtport->dev,
-			"RCV %s LS failed: payload too large (%d)\n",
+		pr_info("{%d}: RCV %s LS failed: payload too large (%d)\n",
+			tgtport->fc_target_port.port_num,
 			(w0->ls_cmd <= NVME_FC_LAST_LS_CMD_VALUE) ?
 				nvmefc_ls_names[w0->ls_cmd] : "",
 			lsreqbuf_len);
@@ -2060,8 +2054,8 @@ nvmet_fc_rcv_ls_req(struct nvmet_fc_target_port *target_port,
 	}
 
 	if (!nvmet_fc_tgtport_get(tgtport)) {
-		dev_info(tgtport->dev,
-			"RCV %s LS failed: target deleting\n",
+		pr_info("{%d}: RCV %s LS failed: target deleting\n",
+			tgtport->fc_target_port.port_num,
 			(w0->ls_cmd <= NVME_FC_LAST_LS_CMD_VALUE) ?
 				nvmefc_ls_names[w0->ls_cmd] : "");
 		return -ESHUTDOWN;
@@ -2069,8 +2063,8 @@ nvmet_fc_rcv_ls_req(struct nvmet_fc_target_port *target_port,
 
 	iod = nvmet_fc_alloc_ls_iod(tgtport);
 	if (!iod) {
-		dev_info(tgtport->dev,
-			"RCV %s LS failed: context allocation failed\n",
+		pr_info("{%d}: RCV %s LS failed: context allocation failed\n",
+			tgtport->fc_target_port.port_num,
 			(w0->ls_cmd <= NVME_FC_LAST_LS_CMD_VALUE) ?
 				nvmefc_ls_names[w0->ls_cmd] : "");
 		nvmet_fc_tgtport_put(tgtport);

-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/5] nvme-fc: misc small improvents
  2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
                   ` (4 preceding siblings ...)
  2025-10-30 10:05 ` [PATCH v2 5/5] nvmet-fc: use pr_* print macros instead of dev_* Daniel Wagner
@ 2025-10-30 21:44 ` Keith Busch
  5 siblings, 0 replies; 7+ messages in thread
From: Keith Busch @ 2025-10-30 21:44 UTC (permalink / raw)
  To: Daniel Wagner
  Cc: Justin Tee, Christoph Hellwig, James Smart, Jens Axboe,
	linux-nvme, linux-kernel

On Thu, Oct 30, 2025 at 11:05:44AM +0100, Daniel Wagner wrote:
> Updated the first patch to use the safe iterator variant as suggested by Justin.
> 
> orig cover text:
> 
> I've collected a bunch of patches from the last debugging session. I think it's
> worth documenting which conditions are expected in the cleanup path by adding a
> bunch of WARNs.
> 
> Also found a deadlock in the nvme-fc code, so this one should definitly go in.

Thanks applied to nvme-6.19.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-10-30 21:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-30 10:05 [PATCH v2 0/5] nvme-fc: misc small improvents Daniel Wagner
2025-10-30 10:05 ` [PATCH v2 1/5] nvme-fc: don't hold rport lock when putting ctrl Daniel Wagner
2025-10-30 10:05 ` [PATCH v2 2/5] nvme-fc: check all request and response have been processed Daniel Wagner
2025-10-30 10:05 ` [PATCH v2 3/5] nvmet-fcloop: " Daniel Wagner
2025-10-30 10:05 ` [PATCH v2 4/5] nvmet-fcloop: remove unused lsdir member Daniel Wagner
2025-10-30 10:05 ` [PATCH v2 5/5] nvmet-fc: use pr_* print macros instead of dev_* Daniel Wagner
2025-10-30 21:44 ` [PATCH v2 0/5] nvme-fc: misc small improvents Keith Busch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).