All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Sagi Grimberg <sagi@grimberg.me>
Cc: Keith Busch <kbusch@kernel.org>,
	Anton Eidelman <anton@lightbitslabs.com>,
	Christoph Hellwig <hch@lst.de>,
	linux-nvme@lists.infradead.org
Subject: Re: [PATCH v2 rfc 1/3] nvme: split nvme_remove_namespaces
Date: Wed, 8 Jul 2020 17:17:52 +0200	[thread overview]
Message-ID: <20200708151752.GA26154@lst.de> (raw)
In-Reply-To: <20200705075935.506535-2-sagi@grimberg.me>


I find the split rather confusing.  So I looked into alternatives
and found that the state change should just be a no-op for the PCIe
reset case.

So what about something like this ontop of your series?

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 4b3bd9b85656e5..feee55903b1968 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -168,9 +168,7 @@ static void nvme_do_delete_ctrl(struct nvme_ctrl *ctrl)
 
 	flush_work(&ctrl->reset_work);
 	nvme_stop_ctrl(ctrl);
-	nvme_prep_remove_namespaces(ctrl);
-	nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING_NOIO);
-	nvme_do_remove_namespaces(ctrl);
+	nvme_remove_namespaces(ctrl);
 	ctrl->ops->delete_ctrl(ctrl);
 	nvme_uninit_ctrl(ctrl);
 }
@@ -4104,8 +4102,16 @@ static void nvme_scan_work(struct work_struct *work)
 	up_write(&ctrl->namespaces_rwsem);
 }
 
-void nvme_prep_remove_namespaces(struct nvme_ctrl *ctrl)
+/*
+ * This function iterates the namespace list unlocked to allow recovery from
+ * controller failure. It is up to the caller to ensure the namespace list is
+ * not modified by scan work while this function is executing.
+ */
+void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
 {
+	struct nvme_ns *ns, *next;
+	LIST_HEAD(ns_list);
+
 	/*
 	 * make sure to requeue I/O to all namespaces as these
 	 * might result from the scan itself and must complete
@@ -4124,13 +4130,9 @@ void nvme_prep_remove_namespaces(struct nvme_ctrl *ctrl)
 	 */
 	if (ctrl->state == NVME_CTRL_DEAD)
 		nvme_kill_queues(ctrl);
-}
-EXPORT_SYMBOL_GPL(nvme_prep_remove_namespaces);
 
-void nvme_do_remove_namespaces(struct nvme_ctrl *ctrl)
-{
-	struct nvme_ns *ns, *next;
-	LIST_HEAD(ns_list);
+	/* this is a no-op when called from the controller reset handler */
+	nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING_NOIO);
 
 	down_write(&ctrl->namespaces_rwsem);
 	list_splice_init(&ctrl->namespaces, &ns_list);
@@ -4139,18 +4141,6 @@ void nvme_do_remove_namespaces(struct nvme_ctrl *ctrl)
 	list_for_each_entry_safe(ns, next, &ns_list, list)
 		nvme_ns_remove(ns);
 }
-EXPORT_SYMBOL_GPL(nvme_do_remove_namespaces);
-
-/*
- * This function iterates the namespace list unlocked to allow recovery from
- * controller failure. It is up to the caller to ensure the namespace list is
- * not modified by scan work while this function is executing.
- */
-void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
-{
-	nvme_prep_remove_namespaces(ctrl);
-	nvme_do_remove_namespaces(ctrl);
-}
 EXPORT_SYMBOL_GPL(nvme_remove_namespaces);
 
 static int nvme_class_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 1e74e0d62e2b11..900b35d47ec7ba 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -168,16 +168,17 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
 static bool nvme_path_is_disabled(struct nvme_ns *ns)
 {
 	/*
-	 * We don't treat NVME_CTRL_DELETING as a disabled path
-	 * as I/O should still be able to complete assuming that
-	 * the controller is connected, otherwise it'll fail
-	 * immediately and return to the requeue list. only fail
-	 * for NVME_CTRL_DELETING_NOIO
+	 * We don't treat NVME_CTRL_DELETING as a disabled path as I/O should
+	 * still be able to complete assuming that the controller is connected.
+	 * Otherwise it will fail immediately and return to the requeue list.
 	 */
-	return (ns->ctrl->state != NVME_CTRL_LIVE &&
-		ns->ctrl->state != NVME_CTRL_DELETING) ||
-		test_bit(NVME_NS_ANA_PENDING, &ns->flags) ||
-		test_bit(NVME_NS_REMOVING, &ns->flags);
+	if (ns->ctrl->state != NVME_CTRL_LIVE &&
+	    ns->ctrl->state != NVME_CTRL_DELETING)
+		return true;
+	if (test_bit(NVME_NS_ANA_PENDING, &ns->flags) ||
+	    test_bit(NVME_NS_REMOVING, &ns->flags))
+		return true;
+	return false;
 }
 
 static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 2ba5d0cee6df25..c22117cd9b41e2 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -552,8 +552,6 @@ void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
 void nvme_start_ctrl(struct nvme_ctrl *ctrl);
 void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_identify(struct nvme_ctrl *ctrl);
-void nvme_prep_remove_namespaces(struct nvme_ctrl *ctrl);
-void nvme_do_remove_namespaces(struct nvme_ctrl *ctrl);
 void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
 
 int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 0f974f932ac4e0..74cced620b0484 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2620,7 +2620,7 @@ static void nvme_reset_work(struct work_struct *work)
 	if (dev->online_queues < 2) {
 		dev_warn(dev->ctrl.device, "IO queues not created\n");
 		nvme_kill_queues(&dev->ctrl);
-		nvme_remove_namespaces(&dev->ctrl);
+		nvme_remove_namespaces(ctrl);
 		nvme_free_tagset(dev);
 	} else {
 		nvme_start_queues(&dev->ctrl);
@@ -2899,9 +2899,7 @@ static void nvme_remove(struct pci_dev *pdev)
 
 	flush_work(&dev->ctrl.reset_work);
 	nvme_stop_ctrl(&dev->ctrl);
-	nvme_prep_remove_namespaces(&dev->ctrl);
-	nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING_NOIO);
-	nvme_do_remove_namespaces(&dev->ctrl);
+	nvme_remove_namespaces(&dev->ctrl);
 	nvme_dev_disable(dev, true);
 	nvme_release_cmb(dev);
 	nvme_free_host_mem(dev);

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

  reply	other threads:[~2020-07-08 15:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-05  7:59 [PATCH v2 rfc 0/3] resolve controller delete hang due to ongoing mpath I/O Sagi Grimberg
2020-07-05  7:59 ` [PATCH v2 rfc 1/3] nvme: split nvme_remove_namespaces Sagi Grimberg
2020-07-08 15:17   ` Christoph Hellwig [this message]
2020-07-10  4:35     ` Sagi Grimberg
2020-07-14 11:06       ` Christoph Hellwig
2020-07-22 22:58         ` Sagi Grimberg
2020-07-05  7:59 ` [PATCH v2 rfc 2/3] nvme: document nvme controller states Sagi Grimberg
2020-07-05  7:59 ` [PATCH v2 rfc 3/3] nvme-core: fix deadlock in disconnect during scan_work and/or ana_work Sagi Grimberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200708151752.GA26154@lst.de \
    --to=hch@lst.de \
    --cc=anton@lightbitslabs.com \
    --cc=kbusch@kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=sagi@grimberg.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.