All of lore.kernel.org
 help / color / mirror / Atom feed
From: hare@suse.de (Hannes Reinecke)
Subject: [PATCH 3/4] nvme: ANA transition timeout handling
Date: Thu,  7 Jun 2018 09:35:55 +0200	[thread overview]
Message-ID: <20180607073556.39050-4-hare@suse.de> (raw)
In-Reply-To: <20180607073556.39050-1-hare@suse.de>

Add a timer for tracking ANA transition timeout, and reset the
controller once the timeout expires.

Signed-off-by: Hannes Reinecke <hare at suse.com>
---
 drivers/nvme/host/core.c      |  3 +++
 drivers/nvme/host/multipath.c | 34 ++++++++++++++++++++++++++++------
 drivers/nvme/host/nvme.h      |  6 ++++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e62de51209b2..3b578ae62cb5 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2378,6 +2378,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
 	ctrl->kas = le16_to_cpu(id->kas);
 	ctrl->max_namespaces = le32_to_cpu(id->mnan);
 	ctrl->anacap = id->anacap;
+	ctrl->anatt = id->anatt;
 	ctrl->nanagrpid = le32_to_cpu(id->nanagrpid);
 	ctrl->anagrpmax = le32_to_cpu(id->anagrpmax);
 
@@ -3025,6 +3026,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	blk_queue_flag_set(QUEUE_FLAG_NONROT, ns->queue);
 	ns->queue->queuedata = ns;
 	ns->ctrl = ctrl;
+	timer_setup(&ns->anatt_timer, nvme_anatt_timedout, 0);
 
 	kref_init(&ns->kref);
 	ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */
@@ -3113,6 +3115,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 			blk_integrity_unregister(ns->disk);
 	}
 
+	del_timer_sync(&ns->anatt_timer);
 	mutex_lock(&ns->ctrl->subsys->lock);
 	nvme_mpath_clear_current_path(ns);
 	list_del_rcu(&ns->siblings);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index d30229a21c97..7a37f5959ad4 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -62,13 +62,12 @@ void nvme_failover_req(struct request *req)
 	 */
 	switch (nvme_req(req)->status & 0x7ff) {
 	case NVME_SC_ANA_TRANSITION:
-		/*
-		 * XXX: We should verify the controller doesn't die on during
-		 * the transition.  But that means we per-group timeout from
-		 * when we first hit the change state, so this won't be
-		 * entirely trivial..
-		 */
 		nvme_update_ana_state(ns, NVME_ANA_CHANGE);
+		if (!timer_pending(&ns->anatt_timer)) {
+			ns->anatt_timer.expires =
+				ns->ctrl->anatt * HZ + jiffies;
+			add_timer(&ns->anatt_timer);
+		}
 		break;
 	case NVME_SC_ANA_PERSISTENT_LOSS:
 		nvme_update_ana_state(ns, NVME_ANA_PERSISTENT_LOSS);
@@ -390,11 +389,34 @@ static int nvme_process_ana_log(struct nvme_ctrl *ctrl, bool groups_only)
 static void nvme_ana_work(struct work_struct *work)
 {
 	struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work);
+	struct nvme_ns *ns;
 
 	nvme_process_ana_log(ctrl, false);
+	down_write(&ctrl->namespaces_rwsem);
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		enum nvme_ana_state state = nvme_ns_ana_state(ns);
+
+		if (timer_pending(&ns->anatt_timer) &&
+		    state != NVME_ANA_CHANGE)
+			del_timer_sync(&ns->anatt_timer);
+		if (!timer_pending(&ns->anatt_timer) &&
+		    state == NVME_ANA_CHANGE) {
+			ns->anatt_timer.expires =
+				ns->ctrl->anatt * HZ + jiffies;
+			add_timer(&ns->anatt_timer);
+		}
+	}
+	up_write(&ctrl->namespaces_rwsem);
 	nvme_kick_requeue_lists(ctrl);
 }
 
+void nvme_anatt_timedout(struct timer_list *t)
+{
+	struct nvme_ns *ns = from_timer(ns, t, anatt_timer);
+
+	nvme_reset_ctrl(ns->ctrl);
+}
+
 int nvme_configure_ana(struct nvme_ctrl *ctrl)
 {
 	int error;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index be2585576bad..d059b5522993 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -200,6 +200,7 @@ struct nvme_ctrl {
 
 	/* asymmetric namespace access: */
 	u8 anacap;
+	u8 anatt;
 	u32 anagrpmax;
 	u32 nanagrpid;
 	enum nvme_ana_state *ana_state;
@@ -301,6 +302,7 @@ struct nvme_ns {
 	struct nvm_dev *ndev;
 	struct kref kref;
 	struct nvme_ns_head *head;
+	struct timer_list anatt_timer;
 
 	int lba_shift;
 	u16 ms;
@@ -469,6 +471,7 @@ void nvme_mpath_add_disk(struct nvme_ns *ns);
 void nvme_mpath_remove_disk(struct nvme_ns_head *head);
 int nvme_configure_ana(struct nvme_ctrl *ctrl);
 void nvme_deconfigure_ana(struct nvme_ctrl *ctrl);
+void nvme_anatt_timedout(struct timer_list *t);
 
 static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns)
 {
@@ -531,6 +534,9 @@ static inline int nvme_configure_ana(struct nvme_ctrl *ctrl)
 static inline void nvme_deconfigure_ana(struct nvme_ctrl *ctrl)
 {
 }
+void nvme_anatt_timedout(struct timer_list *t)
+{
+}
 #endif /* CONFIG_NVME_MULTIPATH */
 
 #ifdef CONFIG_NVM
-- 
2.12.3

  parent reply	other threads:[~2018-06-07  7:35 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-07  7:35 [PATCH 0/4] nvme: ANATT handling Hannes Reinecke
2018-06-07  7:35 ` [PATCH 1/4] nvmet: make ANATT configurable Hannes Reinecke
2018-06-07 12:06   ` Christoph Hellwig
2018-06-07 12:42     ` Hannes Reinecke
2018-06-07 13:03   ` Sagi Grimberg
2018-06-07  7:35 ` [PATCH 2/4] nvmet: ANA transition timeout handling Hannes Reinecke
2018-06-07 12:07   ` Christoph Hellwig
2018-06-07 13:31     ` Hannes Reinecke
2018-06-07 13:41       ` Christoph Hellwig
2018-06-07 13:12   ` Sagi Grimberg
2018-06-07  7:35 ` Hannes Reinecke [this message]
2018-06-07 12:09   ` [PATCH 3/4] nvme: " Christoph Hellwig
2018-06-07 12:52     ` Hannes Reinecke
2018-06-07 13:11       ` Christoph Hellwig
2018-06-07 13:16   ` Sagi Grimberg
2018-06-07 13:26     ` Christoph Hellwig
2018-06-07  7:35 ` [PATCH 4/4] nvme: start ANATT timer on out-of-order state changes Hannes Reinecke
2018-06-07 12:11   ` Christoph Hellwig
2018-06-07 12:37     ` Hannes Reinecke
2018-06-07 13:10       ` Christoph Hellwig
2018-06-07 13:20         ` Hannes Reinecke
2018-06-07 13:46           ` Christoph Hellwig
2018-06-07 14:01             ` Hannes Reinecke
2018-06-07 14:22               ` Christoph Hellwig
2018-06-07 15:20                 ` Sagi Grimberg
2018-06-07 13:20   ` 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=20180607073556.39050-4-hare@suse.de \
    --to=hare@suse.de \
    /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.