* [PATCH 1/2] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl()
2025-11-10 21:19 [PATCH 0/2] Two NVMe/FC bug fixes for -stable Ewan D. Milne
@ 2025-11-10 21:20 ` Ewan D. Milne
2025-11-12 20:56 ` Justin Tee
2025-11-10 21:20 ` [PATCH 2/2] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl() Ewan D. Milne
2025-11-17 16:59 ` [PATCH 0/2] Two NVMe/FC bug fixes for -stable Keith Busch
2 siblings, 1 reply; 6+ messages in thread
From: Ewan D. Milne @ 2025-11-10 21:20 UTC (permalink / raw)
To: linux-nvme
Cc: mpatalan, james.smart, paul.ely, justin.tee, sagi, njavali,
ming.lei, stable
Now target is removed from nvme_fc_ctrl_free() which is the ctrl->ref
release handler. And even admin queue is unquiesced there, this way
is definitely wrong because the ctr->ref is grabbed when submitting
command.
And Marco observed that nvme_fc_ctrl_free() can be called from request
completion code path, and trigger kernel warning since request completes
from softirq context.
Fix the issue by moveing target removal into nvme_fc_delete_ctrl(),
which is also aligned with nvme-tcp and nvme-rdma.
Patch originally proposed by Ming Lei, then modified to move the tagset
removal down to after nvme_fc_delete_association() after further testing.
Cc: Marco Patalano <mpatalan@redhat.com>
Cc: Ewan Milne <emilne@redhat.com>
Cc: James Smart <james.smart@broadcom.com>
Cc: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Cc: stable@vger.kernel.org
Tested-by: Marco Patalano <mpatalan@redhat.com>
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
---
drivers/nvme/host/fc.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index b613fc5966a7..9e1841223e8a 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -2359,17 +2359,11 @@ nvme_fc_ctrl_free(struct kref *ref)
container_of(ref, struct nvme_fc_ctrl, ref);
unsigned long flags;
- if (ctrl->ctrl.tagset)
- nvme_remove_io_tag_set(&ctrl->ctrl);
-
/* remove from rport list */
spin_lock_irqsave(&ctrl->rport->lock, flags);
list_del(&ctrl->ctrl_list);
spin_unlock_irqrestore(&ctrl->rport->lock, flags);
- nvme_unquiesce_admin_queue(&ctrl->ctrl);
- nvme_remove_admin_tag_set(&ctrl->ctrl);
-
kfree(ctrl->queues);
put_device(ctrl->dev);
@@ -3265,11 +3259,18 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl)
cancel_work_sync(&ctrl->ioerr_work);
cancel_delayed_work_sync(&ctrl->connect_work);
+
/*
* kill the association on the link side. this will block
* waiting for io to terminate
*/
nvme_fc_delete_association(ctrl);
+
+ if (ctrl->ctrl.tagset)
+ nvme_remove_io_tag_set(&ctrl->ctrl);
+
+ nvme_unquiesce_admin_queue(&ctrl->ctrl);
+ nvme_remove_admin_tag_set(&ctrl->ctrl);
}
static void
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl()
2025-11-10 21:20 ` [PATCH 1/2] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl() Ewan D. Milne
@ 2025-11-12 20:56 ` Justin Tee
0 siblings, 0 replies; 6+ messages in thread
From: Justin Tee @ 2025-11-12 20:56 UTC (permalink / raw)
To: Ewan D. Milne, linux-nvme
Cc: mpatalan, james.smart, paul.ely, justin.tee, sagi, njavali,
ming.lei, stable
Reviewed-by: Justin Tee <justin.tee@broadcom.com>
Regards,
Justin
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl()
2025-11-10 21:19 [PATCH 0/2] Two NVMe/FC bug fixes for -stable Ewan D. Milne
2025-11-10 21:20 ` [PATCH 1/2] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl() Ewan D. Milne
@ 2025-11-10 21:20 ` Ewan D. Milne
2025-11-12 20:57 ` Justin Tee
2025-11-17 16:59 ` [PATCH 0/2] Two NVMe/FC bug fixes for -stable Keith Busch
2 siblings, 1 reply; 6+ messages in thread
From: Ewan D. Milne @ 2025-11-10 21:20 UTC (permalink / raw)
To: linux-nvme
Cc: mpatalan, james.smart, paul.ely, justin.tee, sagi, njavali,
ming.lei, stable
nvme_fc_delete_assocation() waits for pending I/O to complete before
returning, and an error can cause ->ioerr_work to be queued after
cancel_work_sync() had been called. Move the call to cancel_work_sync() to
be after nvme_fc_delete_association() to ensure ->ioerr_work is not running
when the nvme_fc_ctrl object is freed. Otherwise the following can occur:
[ 1135.911754] list_del corruption, ff2d24c8093f31f8->next is NULL
[ 1135.917705] ------------[ cut here ]------------
[ 1135.922336] kernel BUG at lib/list_debug.c:52!
[ 1135.926784] Oops: invalid opcode: 0000 [#1] SMP NOPTI
[ 1135.931851] CPU: 48 UID: 0 PID: 726 Comm: kworker/u449:23 Kdump: loaded Not tainted 6.12.0 #1 PREEMPT(voluntary)
[ 1135.943490] Hardware name: Dell Inc. PowerEdge R660/0HGTK9, BIOS 2.5.4 01/16/2025
[ 1135.950969] Workqueue: 0x0 (nvme-wq)
[ 1135.954673] RIP: 0010:__list_del_entry_valid_or_report.cold+0xf/0x6f
[ 1135.961041] Code: c7 c7 98 68 72 94 e8 26 45 fe ff 0f 0b 48 c7 c7 70 68 72 94 e8 18 45 fe ff 0f 0b 48 89 fe 48 c7 c7 80 69 72 94 e8 07 45 fe ff <0f> 0b 48 89 d1 48 c7 c7 a0 6a 72 94 48 89 c2 e8 f3 44 fe ff 0f 0b
[ 1135.979788] RSP: 0018:ff579b19482d3e50 EFLAGS: 00010046
[ 1135.985015] RAX: 0000000000000033 RBX: ff2d24c8093f31f0 RCX: 0000000000000000
[ 1135.992148] RDX: 0000000000000000 RSI: ff2d24d6bfa1d0c0 RDI: ff2d24d6bfa1d0c0
[ 1135.999278] RBP: ff2d24c8093f31f8 R08: 0000000000000000 R09: ffffffff951e2b08
[ 1136.006413] R10: ffffffff95122ac8 R11: 0000000000000003 R12: ff2d24c78697c100
[ 1136.013546] R13: fffffffffffffff8 R14: 0000000000000000 R15: ff2d24c78697c0c0
[ 1136.020677] FS: 0000000000000000(0000) GS:ff2d24d6bfa00000(0000) knlGS:0000000000000000
[ 1136.028765] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1136.034510] CR2: 00007fd207f90b80 CR3: 000000163ea22003 CR4: 0000000000f73ef0
[ 1136.041641] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1136.048776] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
[ 1136.055910] PKRU: 55555554
[ 1136.058623] Call Trace:
[ 1136.061074] <TASK>
[ 1136.063179] ? show_trace_log_lvl+0x1b0/0x2f0
[ 1136.067540] ? show_trace_log_lvl+0x1b0/0x2f0
[ 1136.071898] ? move_linked_works+0x4a/0xa0
[ 1136.075998] ? __list_del_entry_valid_or_report.cold+0xf/0x6f
[ 1136.081744] ? __die_body.cold+0x8/0x12
[ 1136.085584] ? die+0x2e/0x50
[ 1136.088469] ? do_trap+0xca/0x110
[ 1136.091789] ? do_error_trap+0x65/0x80
[ 1136.095543] ? __list_del_entry_valid_or_report.cold+0xf/0x6f
[ 1136.101289] ? exc_invalid_op+0x50/0x70
[ 1136.105127] ? __list_del_entry_valid_or_report.cold+0xf/0x6f
[ 1136.110874] ? asm_exc_invalid_op+0x1a/0x20
[ 1136.115059] ? __list_del_entry_valid_or_report.cold+0xf/0x6f
[ 1136.120806] move_linked_works+0x4a/0xa0
[ 1136.124733] worker_thread+0x216/0x3a0
[ 1136.128485] ? __pfx_worker_thread+0x10/0x10
[ 1136.132758] kthread+0xfa/0x240
[ 1136.135904] ? __pfx_kthread+0x10/0x10
[ 1136.139657] ret_from_fork+0x31/0x50
[ 1136.143236] ? __pfx_kthread+0x10/0x10
[ 1136.146988] ret_from_fork_asm+0x1a/0x30
[ 1136.150915] </TASK>
Fixes: 19fce0470f05 ("nvme-fc: avoid calling _nvme_fc_abort_outstanding_ios from interrupt context")
Cc: stable@vger.kernel.org
Tested-by: Marco Patalano <mpatalan@redhat.com>
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
---
drivers/nvme/host/fc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 9e1841223e8a..bce3ea13c200 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -3257,7 +3257,6 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);
- cancel_work_sync(&ctrl->ioerr_work);
cancel_delayed_work_sync(&ctrl->connect_work);
/*
@@ -3265,6 +3264,7 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl)
* waiting for io to terminate
*/
nvme_fc_delete_association(ctrl);
+ cancel_work_sync(&ctrl->ioerr_work);
if (ctrl->ctrl.tagset)
nvme_remove_io_tag_set(&ctrl->ctrl);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/2] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl()
2025-11-10 21:20 ` [PATCH 2/2] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl() Ewan D. Milne
@ 2025-11-12 20:57 ` Justin Tee
0 siblings, 0 replies; 6+ messages in thread
From: Justin Tee @ 2025-11-12 20:57 UTC (permalink / raw)
To: Ewan D. Milne, linux-nvme
Cc: mpatalan, james.smart, paul.ely, justin.tee, sagi, njavali,
ming.lei, stable
Reviewed-by: Justin Tee <justin.tee@broadcom.com>
Regards,
Justin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Two NVMe/FC bug fixes for -stable
2025-11-10 21:19 [PATCH 0/2] Two NVMe/FC bug fixes for -stable Ewan D. Milne
2025-11-10 21:20 ` [PATCH 1/2] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl() Ewan D. Milne
2025-11-10 21:20 ` [PATCH 2/2] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl() Ewan D. Milne
@ 2025-11-17 16:59 ` Keith Busch
2 siblings, 0 replies; 6+ messages in thread
From: Keith Busch @ 2025-11-17 16:59 UTC (permalink / raw)
To: Ewan D. Milne
Cc: linux-nvme, mpatalan, james.smart, paul.ely, justin.tee, sagi,
njavali, ming.lei, stable
On Mon, Nov 10, 2025 at 04:19:59PM -0500, Ewan D. Milne wrote:
> This patch series contains two fixes to the NVMe/FC transport code.
>
> The first one fixes a problem where we prematurely free the tagset
> based on an observation and a fix originally proposed by Ming Lei,
> with a further modification based on more extensive testing.
>
> The second one fixes a problem where we sometimes still had a
> workqueue item queued when we freed the nvme_fc_ctrl.
Thanks, applied to nvme-6.18.
^ permalink raw reply [flat|nested] 6+ messages in thread