[PATCH rfc 30/30] nvme: Add queue freeze/unfreeze handling on controller resets
Sagi Grimberg
sagi at grimberg.me
Sun Jun 18 08:22:04 PDT 2017
Just copy what we have in nvme-pci. It's a generic flow anyway.
Signed-off-by: Sagi Grimberg <sagi at grimberg.me>
---
drivers/nvme/host/core.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f4800b8e47a0..959b6c39f22c 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2901,15 +2901,40 @@ EXPORT_SYMBOL_GPL(nvme_configure_admin_queue);
static void nvme_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown)
{
+ bool dead = true;
+
nvme_stop_keep_alive(ctrl);
cancel_work_sync(&ctrl->err_work);
cancel_delayed_work_sync(&ctrl->reconnect_work);
if (ctrl->max_queues > 1) {
+ u32 csts;
+
+ if (!ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) {
+ nvme_start_freeze(ctrl);
+ dead = !!((csts & NVME_CSTS_CFS) ||
+ !(csts & NVME_CSTS_RDY));
+ }
+
+ /*
+ * Give the controller a chance to complete all entered requests
+ * if doing a safe shutdown.
+ */
+ if (!dead && shutdown)
+ nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT);
+
nvme_stop_queues(ctrl);
blk_mq_tagset_busy_iter(ctrl->tagset,
nvme_cancel_request, ctrl);
nvme_destroy_io_queues(ctrl, shutdown);
+
+ /*
+ * The driver will not be starting up queues again if shutting
+ * down so must flush all entered requests to their failed
+ * completion to avoid deadlocking blk-mq hot-cpu notifier.
+ */
+ if (shutdown)
+ nvme_start_queues(ctrl);
}
if (shutdown)
@@ -2991,6 +3016,8 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
if (ctrl->queue_count > 1) {
nvme_start_queues(ctrl);
+ nvme_wait_freeze(ctrl);
+ nvme_unfreeze(ctrl);
nvme_queue_scan(ctrl);
nvme_queue_async_events(ctrl);
}
--
2.7.4
More information about the Linux-nvme
mailing list