]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nvme-fc: Do not cancel requests in io target before it is initialized
authorMohamed Khalfella <mkhalfella@purestorage.com>
Thu, 28 May 2026 09:27:34 +0000 (11:27 +0200)
committerKeith Busch <kbusch@kernel.org>
Wed, 10 Jun 2026 14:35:01 +0000 (07:35 -0700)
A new nvme-fc controller in CONNECTING state sees admin request timeout
schedules ctrl->ioerr_work to abort inflight requests. This ends up
calling __nvme_fc_abort_outstanding_ios() which aborts requests in both
admin and io tagsets. In case fc_ctrl->tag_set was not initialized we
see the warning below. This is because ctrl.queue_count is initialized
early in nvme_fc_alloc_ctrl().

nvme nvme0: NVME-FC{0}: starting error recovery Connectivity Loss
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe
lpfc 0000:ab:00.0: queue 0 connect admin queue failed (-6).
you didn't initialize this object before use?
turning off the locking correctness validator.
Workqueue: nvme-reset-wq nvme_fc_ctrl_ioerr_work [nvme_fc]
Call Trace:
 <TASK>
 dump_stack_lvl+0x57/0x80
 register_lock_class+0x567/0x580
 __lock_acquire+0x330/0xb90
 lock_acquire.part.0+0xad/0x210
 blk_mq_tagset_busy_iter+0xf9/0xc00
 __nvme_fc_abort_outstanding_ios+0x23f/0x320 [nvme_fc]
 nvme_fc_ctrl_ioerr_work+0x172/0x210 [nvme_fc]
 process_one_work+0x82c/0x1450
 worker_thread+0x5ee/0xfd0
 kthread+0x3a0/0x750
 ret_from_fork+0x439/0x670
 ret_from_fork_asm+0x1a/0x30
 </TASK>

Update the check in __nvme_fc_abort_outstanding_ios() confirm that io
tagset was created before iterating over busy requests. Also make sure
to cancel ctrl->ioerr_work before removing io tagset.

Reviewed-by: Randy Jennings <randyj@purestorage.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Daniel Wagner <dwagner@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Signed-off-by: James Smart <jsmart833426@gmail.com>
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/fc.c

index 2c9a6d3c9797a76734b0a9cd349ca835473185bd..04363b9c4489e0f1439730843c399e6142f02c3d 100644 (file)
@@ -2461,7 +2461,7 @@ __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues)
         * io requests back to the block layer as part of normal completions
         * (but with error status).
         */
-       if (ctrl->ctrl.queue_count > 1) {
+       if (ctrl->ctrl.queue_count > 1 && ctrl->ctrl.tagset) {
                nvme_quiesce_io_queues(&ctrl->ctrl);
                nvme_sync_io_queues(&ctrl->ctrl);
                blk_mq_tagset_busy_iter(&ctrl->tag_set,
@@ -2900,6 +2900,11 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
 out_delete_hw_queues:
        nvme_fc_delete_hw_io_queues(ctrl);
 out_cleanup_tagset:
+       /*
+        * In CONNECTING state ctrl->ioerr_work will abort both admin
+        * and io tagsets. Cancel it first before removing io tagset.
+        */
+       cancel_work_sync(&ctrl->ioerr_work);
        nvme_remove_io_tag_set(&ctrl->ctrl);
        nvme_fc_free_io_queues(ctrl);