[PATCH] nvme: invalidate paths when removing contoller

Hannes Reinecke hare at suse.de
Tue Oct 19 08:48:23 PDT 2021


When the I/O from the initial partition scan encounters an error
it will not necessarily be failed, but might trigger a reconnect
with the I/O itself being requeued.
Upon disconnect we need to ensure to flush the requeue list
independent on the current path, otherwise the I/O will never
complete.

Signed-off-by: Hannes Reinecke <hare at suse.de>
---
 drivers/nvme/host/core.c      |  2 +-
 drivers/nvme/host/multipath.c | 13 +++++++++++++
 drivers/nvme/host/nvme.h      |  4 ++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 4d676b5db413..380689a1407b 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4137,7 +4137,7 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
 	 * might result from the scan itself and must complete
 	 * for the scan_work to make progress
 	 */
-	nvme_mpath_clear_ctrl_paths(ctrl);
+	nvme_mpath_invalidate_paths(ctrl);
 
 	/* prevent racing with ns scanning */
 	flush_work(&ctrl->scan_work);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index fb96e900dd3a..a86fef7b1c28 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -165,6 +165,19 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
 		rcu_assign_pointer(head->current_path[node], NULL);
 }
 
+void nvme_mpath_invalidate_paths(struct nvme_ctrl *ctrl)
+{
+	struct nvme_ns *ns;
+
+	down_read(&ctrl->namespaces_rwsem);
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		clear_bit(NVME_NS_READY, &ns->flags);
+		if (ns->head->disk)
+			kblockd_schedule_work(&ns->head->requeue_work);
+	}
+	up_read(&ctrl->namespaces_rwsem);
+}
+
 static bool nvme_path_is_disabled(struct nvme_ns *ns)
 {
 	/*
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 2c7a77f600f8..313e54d37e16 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -752,6 +752,7 @@ void nvme_mpath_stop(struct nvme_ctrl *ctrl);
 bool nvme_mpath_clear_current_path(struct nvme_ns *ns);
 void nvme_mpath_revalidate_paths(struct nvme_ns *ns);
 void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl);
+void nvme_mpath_invalidate_paths(struct nvme_ctrl *ctrl);
 void nvme_mpath_shutdown_disk(struct nvme_ns_head *head);
 
 static inline void nvme_trace_bio_complete(struct request *req)
@@ -804,6 +805,9 @@ static inline void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
 static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
 {
 }
+void nvme_mpath_invalidate_paths(struct nvme_ctrl *ctrl)
+{
+}
 static inline void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
 {
 }
-- 
2.29.2




More information about the Linux-nvme mailing list