* [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).