Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl()

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>
Reviewed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Ewan D. Milne and committed by
Keith Busch
ea3442ef 6d87cd53

+7 -6
+7 -6
drivers/nvme/host/fc.c
··· 2355 2355 container_of(ref, struct nvme_fc_ctrl, ref); 2356 2356 unsigned long flags; 2357 2357 2358 - if (ctrl->ctrl.tagset) 2359 - nvme_remove_io_tag_set(&ctrl->ctrl); 2360 - 2361 2358 /* remove from rport list */ 2362 2359 spin_lock_irqsave(&ctrl->rport->lock, flags); 2363 2360 list_del(&ctrl->ctrl_list); 2364 2361 spin_unlock_irqrestore(&ctrl->rport->lock, flags); 2365 - 2366 - nvme_unquiesce_admin_queue(&ctrl->ctrl); 2367 - nvme_remove_admin_tag_set(&ctrl->ctrl); 2368 2362 2369 2363 kfree(ctrl->queues); 2370 2364 ··· 3255 3261 3256 3262 cancel_work_sync(&ctrl->ioerr_work); 3257 3263 cancel_delayed_work_sync(&ctrl->connect_work); 3264 + 3258 3265 /* 3259 3266 * kill the association on the link side. this will block 3260 3267 * waiting for io to terminate 3261 3268 */ 3262 3269 nvme_fc_delete_association(ctrl); 3270 + 3271 + if (ctrl->ctrl.tagset) 3272 + nvme_remove_io_tag_set(&ctrl->ctrl); 3273 + 3274 + nvme_unquiesce_admin_queue(&ctrl->ctrl); 3275 + nvme_remove_admin_tag_set(&ctrl->ctrl); 3263 3276 } 3264 3277 3265 3278 static void