1 From 786129269de8bf8d722b19ff691533dc0c3b5d6a Mon Sep 17 00:00:00 2001
2 From: Yufen Yu <yuyufen@huawei.com>
3 Date: Wed, 13 Mar 2019 18:54:59 +0100
4 Subject: nvme-loop: init nvmet_ctrl fatal_err_work when allocate
6 [ Upstream commit d11de63f2b519f0a162b834013b6d3a46dbf3886 ]
8 After commit 4d43d395fe (workqueue: Try to catch flush_work() without
9 INIT_WORK()), it can cause warning when delete nvme-loop device, trace
12 [ 76.601272] Call Trace:
13 [ 76.601646] ? del_timer+0x72/0xa0
14 [ 76.602156] __cancel_work_timer+0x1ae/0x270
15 [ 76.602791] cancel_work_sync+0x14/0x20
16 [ 76.603407] nvmet_ctrl_free+0x1b7/0x2f0 [nvmet]
17 [ 76.604091] ? free_percpu+0x168/0x300
18 [ 76.604652] nvmet_sq_destroy+0x106/0x240 [nvmet]
19 [ 76.605346] nvme_loop_destroy_admin_queue+0x30/0x60 [nvme_loop]
20 [ 76.606220] nvme_loop_shutdown_ctrl+0xc3/0xf0 [nvme_loop]
21 [ 76.607026] nvme_loop_delete_ctrl_host+0x19/0x30 [nvme_loop]
22 [ 76.607871] nvme_do_delete_ctrl+0x75/0xb0
23 [ 76.608477] nvme_sysfs_delete+0x7d/0xc0
24 [ 76.609057] dev_attr_store+0x24/0x40
25 [ 76.609603] sysfs_kf_write+0x4c/0x60
26 [ 76.610144] kernfs_fop_write+0x19a/0x260
27 [ 76.610742] __vfs_write+0x1c/0x60
28 [ 76.611246] vfs_write+0xfa/0x280
29 [ 76.611739] ksys_write+0x6e/0x120
30 [ 76.612238] __x64_sys_write+0x1e/0x30
31 [ 76.612787] do_syscall_64+0xbf/0x3a0
32 [ 76.613329] entry_SYSCALL_64_after_hwframe+0x44/0xa9
34 We fix it by moving fatal_err_work init to nvmet_alloc_ctrl(), which may
37 Signed-off-by: Yufen Yu <yuyufen@huawei.com>
38 Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
39 Reviewed-by: Bart Van Assche <bvanassche@acm.org>
40 Signed-off-by: Christoph Hellwig <hch@lst.de>
41 Signed-off-by: Jens Axboe <axboe@kernel.dk>
42 Signed-off-by: Sasha Levin <sashal@kernel.org>
44 drivers/nvme/target/core.c | 20 ++++++++++----------
45 1 file changed, 10 insertions(+), 10 deletions(-)
47 diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
48 index 5fa7856f6b34..09a39f4aaf82 100644
49 --- a/drivers/nvme/target/core.c
50 +++ b/drivers/nvme/target/core.c
51 @@ -746,6 +746,15 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys,
52 return __nvmet_host_allowed(subsys, hostnqn);
55 +static void nvmet_fatal_error_handler(struct work_struct *work)
57 + struct nvmet_ctrl *ctrl =
58 + container_of(work, struct nvmet_ctrl, fatal_err_work);
60 + pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid);
61 + ctrl->ops->delete_ctrl(ctrl);
64 u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
65 struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp)
67 @@ -785,6 +794,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
69 INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work);
70 INIT_LIST_HEAD(&ctrl->async_events);
71 + INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler);
73 memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE);
74 memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE);
75 @@ -887,21 +897,11 @@ void nvmet_ctrl_put(struct nvmet_ctrl *ctrl)
76 kref_put(&ctrl->ref, nvmet_ctrl_free);
79 -static void nvmet_fatal_error_handler(struct work_struct *work)
81 - struct nvmet_ctrl *ctrl =
82 - container_of(work, struct nvmet_ctrl, fatal_err_work);
84 - pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid);
85 - ctrl->ops->delete_ctrl(ctrl);
88 void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl)
90 mutex_lock(&ctrl->lock);
91 if (!(ctrl->csts & NVME_CSTS_CFS)) {
92 ctrl->csts |= NVME_CSTS_CFS;
93 - INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler);
94 schedule_work(&ctrl->fatal_err_work);
96 mutex_unlock(&ctrl->lock);