Commit f6c8e432 authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Christoph Hellwig

nvme: flush namespace scanning work just before removing namespaces

nvme_stop_ctrl can be called also for reset flow and there is no need to
flush the scan_work as namespaces are not being removed. This can cause
deadlock in rdma, fc and loop drivers since nvme_stop_ctrl barriers
before controller teardown (and specifically I/O cancellation of the
scan_work itself) takes place, but the scan_work will be blocked anyways
so there is no need to flush it.

Instead, move scan_work flush to nvme_remove_namespaces() where it really
needs to flush.
Reported-by: default avatarMing Lei <ming.lei@redhat.com>
Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed by: James Smart <jsmart2021@gmail.com>
Tested-by: default avatarEwan D. Milne <emilne@redhat.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 14a1336e
...@@ -3314,6 +3314,9 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) ...@@ -3314,6 +3314,9 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
struct nvme_ns *ns, *next; struct nvme_ns *ns, *next;
LIST_HEAD(ns_list); LIST_HEAD(ns_list);
/* prevent racing with ns scanning */
flush_work(&ctrl->scan_work);
/* /*
* The dead states indicates the controller was not gracefully * The dead states indicates the controller was not gracefully
* disconnected. In that case, we won't be able to flush any data while * disconnected. In that case, we won't be able to flush any data while
...@@ -3476,7 +3479,6 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) ...@@ -3476,7 +3479,6 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl)
nvme_mpath_stop(ctrl); nvme_mpath_stop(ctrl);
nvme_stop_keep_alive(ctrl); nvme_stop_keep_alive(ctrl);
flush_work(&ctrl->async_event_work); flush_work(&ctrl->async_event_work);
flush_work(&ctrl->scan_work);
cancel_work_sync(&ctrl->fw_act_work); cancel_work_sync(&ctrl->fw_act_work);
if (ctrl->ops->stop_ctrl) if (ctrl->ops->stop_ctrl)
ctrl->ops->stop_ctrl(ctrl); ctrl->ops->stop_ctrl(ctrl);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment