[PATCH V4 5/7] nvme: core: introduce 'reset_lock' for sync reset state and reset activities

Ming Lei ming.lei at redhat.com
Sat May 5 06:59:03 PDT 2018


NVMe PCI may start a new reset context to run nested reset for recovering
from reset context, and we may not change the rule of state machine until
other kinds of NVMe controller support that, so use the 'reset_lock' to sync
the state change here.

Cc: Jianchao Wang <jianchao.w.wang at oracle.com>
Cc: Christoph Hellwig <hch at lst.de>
Cc: Sagi Grimberg <sagi at grimberg.me>
Cc: linux-nvme at lists.infradead.org
Cc: Laurence Oberman <loberman at redhat.com>
Signed-off-by: Ming Lei <ming.lei at redhat.com>
---
 drivers/nvme/host/core.c | 20 +++++++++++++++++---
 drivers/nvme/host/nvme.h |  3 +++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9df4f71e58ca..3aaee4dbf58e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -100,13 +100,25 @@ static struct class *nvme_subsys_class;
 static void nvme_ns_remove(struct nvme_ns *ns);
 static int nvme_revalidate_disk(struct gendisk *disk);
 
+/*
+ * NVMe PCI may support nested reset for recovering from reset context,
+ * and we may not change the rule of state machine until other kinds of
+ * NVMe controller support that, so use the 'reset_lock' to sync the
+ * state change here.
+ */
 int nvme_reset_ctrl(struct nvme_ctrl *ctrl)
 {
+	int ret = -EBUSY;
+
+	mutex_lock(&ctrl->reset_lock);
 	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING))
-		return -EBUSY;
+		goto fail;
 	if (!queue_work(nvme_reset_wq, &ctrl->reset_work))
-		return -EBUSY;
-	return 0;
+		goto fail;
+	ret = 0;
+ fail:
+	mutex_unlock(&ctrl->reset_lock);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nvme_reset_ctrl);
 
@@ -3447,6 +3459,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
 	INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work);
 	INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work);
 
+	mutex_init(&ctrl->reset_lock);
+
 	ret = ida_simple_get(&nvme_instance_ida, 0, 0, GFP_KERNEL);
 	if (ret < 0)
 		goto out;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 061fecfd44f5..99f55c6f69f8 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -146,6 +146,9 @@ struct nvme_ctrl {
 	struct device ctrl_device;
 	struct device *device;	/* char device */
 	struct cdev cdev;
+
+	/* sync reset state update and related reset activities */
+	struct mutex reset_lock;
 	struct work_struct reset_work;
 	struct work_struct delete_work;
 
-- 
2.9.5




More information about the Linux-nvme mailing list