@@ -4579,17 +4579,32 @@ void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl)
}
EXPORT_SYMBOL_GPL(nvme_mark_namespaces_dead);
-void nvme_unfreeze(struct nvme_ctrl *ctrl)
+static void __nvme_unfreeze(struct nvme_ctrl *ctrl, bool force)
{
struct nvme_ns *ns;
down_read(&ctrl->namespaces_rwsem);
- list_for_each_entry(ns, &ctrl->namespaces, list)
- blk_mq_unfreeze_queue(ns->queue);
+ list_for_each_entry(ns, &ctrl->namespaces, list) {
+ if (force)
+ blk_mq_unfreeze_queue_force(ns->queue);
+ else
+ blk_mq_unfreeze_queue(ns->queue);
+ }
up_read(&ctrl->namespaces_rwsem);
}
+
+void nvme_unfreeze(struct nvme_ctrl *ctrl)
+{
+ __nvme_unfreeze(ctrl, false);
+}
EXPORT_SYMBOL_GPL(nvme_unfreeze);
+void nvme_unfreeze_force(struct nvme_ctrl *ctrl)
+{
+ __nvme_unfreeze(ctrl, true);
+}
+EXPORT_SYMBOL_GPL(nvme_unfreeze_force);
+
int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout)
{
struct nvme_ns *ns;
@@ -765,6 +765,7 @@ void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl);
void nvme_sync_queues(struct nvme_ctrl *ctrl);
void nvme_sync_io_queues(struct nvme_ctrl *ctrl);
void nvme_unfreeze(struct nvme_ctrl *ctrl);
+void nvme_unfreeze_force(struct nvme_ctrl *ctrl);
void nvme_wait_freeze(struct nvme_ctrl *ctrl);
int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout);
void nvme_start_freeze(struct nvme_ctrl *ctrl);
Add nvme_unfreeze_force() for fixing IO hang during removing namespaces from error recovery. Signed-off-by: Ming Lei <ming.lei@redhat.com> --- drivers/nvme/host/core.c | 21 ++++++++++++++++++--- drivers/nvme/host/nvme.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)