linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: hare@suse.de (Hannes Reinecke)
Subject: [PATCH 02/10] nvme: ANA transition timeout handling
Date: Tue, 29 May 2018 12:14:23 +0200	[thread overview]
Message-ID: <20180529101431.62271-3-hare@suse.de> (raw)
In-Reply-To: <20180529101431.62271-1-hare@suse.de>

Use delayed work for processing ANA log pages, and resubmit the
workqueue function in case of an error or if a state is found to
be in 'transitioning'.

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

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index b1e4f56a55ed..1be424053f47 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1516,6 +1516,12 @@ static int nvme_revalidate_disk(struct gendisk *disk)
 		goto out;
 	}
 
+	if (ns->anagrpid != le32_to_cpu(id->anagrpid)) {
+		dev_warn(ctrl->device, "nsid %d ANA group id changed\n",
+			 ns->head->ns_id);
+		queue_delayed_work(nvme_wq, &ctrl->ana_work, 0);
+	}
+
 	__nvme_revalidate_disk(disk, id);
 	nvme_report_ns_ids(ctrl, ns->head->ns_id, id, &ids);
 	if (!nvme_ns_ids_equal(&ns->head->ids, &ids)) {
@@ -2390,6 +2396,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);
 
@@ -3415,7 +3422,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
 	case NVME_AER_NOTICE_ANA:
 		if (WARN_ON_ONCE(!ctrl->ana_log_buf))
 			break;
-		queue_work(nvme_wq, &ctrl->ana_work);
+		queue_delayed_work(nvme_wq, &ctrl->ana_work, 0);
 		break;
 	default:
 		dev_warn(ctrl->device, "async event result %08x\n", result);
@@ -3452,7 +3459,7 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl)
 	nvme_stop_keep_alive(ctrl);
 	flush_work(&ctrl->async_event_work);
 	flush_work(&ctrl->scan_work);
-	cancel_work_sync(&ctrl->ana_work);
+	cancel_delayed_work_sync(&ctrl->ana_work);
 	cancel_work_sync(&ctrl->fw_act_work);
 	if (ctrl->ops->stop_ctrl)
 		ctrl->ops->stop_ctrl(ctrl);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 1a8791340862..2fcaf50d84e2 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -69,6 +69,8 @@ void nvme_failover_req(struct request *req)
 		 * entirely trivial..
 		 */
 		nvme_update_ana_state(ns, NVME_ANA_CHANGE);
+		queue_delayed_work(nvme_wq, &ns->ctrl->ana_work,
+				   ns->ctrl->anatt * HZ);
 		break;
 	case NVME_SC_ANA_PERSISTENT_LOSS:
 		nvme_update_ana_state(ns, NVME_ANA_PERSISTENT_LOSS);
@@ -309,7 +311,7 @@ static int nvme_process_ana_log(struct nvme_ctrl *ctrl, bool groups_only)
 {
 	void *base = ctrl->ana_log_buf;
 	size_t offset = sizeof(struct nvme_ana_rsp_hdr);
-	int error, i;
+	int error = 0, i;
 
 	/*
 	 * If anagrpid never changes we don't need to process the namespace
@@ -323,7 +325,7 @@ static int nvme_process_ana_log(struct nvme_ctrl *ctrl, bool groups_only)
 			ctrl->ana_log_buf, ctrl->ana_log_size, 0);
 	if (error) {
 		dev_warn(ctrl->device, "Failed to get ANA log: %d\n", error);
-		return error;
+		return -EIO;
 	}
 
 	for (i = 0; i < le16_to_cpu(ctrl->ana_log_buf->ngrps); i++) {
@@ -345,6 +347,8 @@ static int nvme_process_ana_log(struct nvme_ctrl *ctrl, bool groups_only)
 		dev_info(ctrl->device, "ANA group %d: %s.\n",
 				grpid, nvme_ana_state_names[desc->state]);
 		WRITE_ONCE(ctrl->ana_state[grpid], desc->state);
+		if (desc->state == NVME_ANA_CHANGE)
+			error = -EAGAIN;
 		offset += sizeof(*desc);
 		if (!nr_nsids)
 			continue;
@@ -372,14 +376,31 @@ static int nvme_process_ana_log(struct nvme_ctrl *ctrl, bool groups_only)
 			return -EINVAL;
 	}
 
-	return 0;
+	return error;
 }
 
 static void nvme_ana_work(struct work_struct *work)
 {
-	struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work);
+	struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl,
+					      ana_work.work);
+	int ret;
+
+	if (!ctrl->ana_log_buf)
+		return;
+	if (ctrl->state != NVME_CTRL_LIVE)
+		return;
+	ret = nvme_process_ana_log(ctrl, false);
+	if (ret == -EAGAIN || ret == -EIO) {
+		unsigned long log_delay = ctrl->anatt * HZ;
 
-	nvme_process_ana_log(ctrl, false);
+		/*
+		 * In case of an I/O error just add a small delay to not hit
+		 * the target too hard
+		 */
+		if (ret == -EIO)
+			log_delay = msecs_to_jiffies(NVME_ANA_LOG_DELAY);
+		queue_delayed_work(nvme_wq, &ctrl->ana_work, log_delay);
+	}
 	nvme_kick_requeue_lists(ctrl);
 }
 
@@ -404,7 +425,7 @@ int nvme_configure_ana(struct nvme_ctrl *ctrl)
 		return 0;
 	}
 
-	INIT_WORK(&ctrl->ana_work, nvme_ana_work);
+	INIT_DELAYED_WORK(&ctrl->ana_work, nvme_ana_work);
 	ctrl->ana_state = kcalloc(ctrl->anagrpmax, sizeof(*ctrl->ana_state),
 			GFP_KERNEL);
 	if (!ctrl->ana_state)
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 4a29c736370f..53cb7f8a6267 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -32,6 +32,7 @@ extern unsigned int admin_timeout;
 
 #define NVME_DEFAULT_KATO	5
 #define NVME_KATO_GRACE		10
+#define NVME_ANA_LOG_DELAY	500
 
 extern struct workqueue_struct *nvme_wq;
 extern struct workqueue_struct *nvme_reset_wq;
@@ -195,12 +196,13 @@ struct nvme_ctrl {
 
 	/* asymmetric namespace access: */
 	u8 anacap;
+	u8 anatt;
 	u32 anagrpmax;
 	u32 nanagrpid;
 	enum nvme_ana_state *ana_state;
 	size_t ana_log_size;
 	struct nvme_ana_rsp_hdr *ana_log_buf;
-	struct work_struct ana_work;
+	struct delayed_work ana_work;
 
 	/* Power saving configuration */
 	u64 ps_max_latency_us;
-- 
2.12.3

  parent reply	other threads:[~2018-05-29 10:14 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-29 10:14 [PATCH 00/10] nvme: ANA fixups Hannes Reinecke
2018-05-29 10:14 ` [PATCH 01/10] nvme: add missing kfree() in nvme_configure_ana() Hannes Reinecke
2018-05-29 12:16   ` Johannes Thumshirn
2018-05-29 12:39   ` Christoph Hellwig
2018-05-29 10:14 ` Hannes Reinecke [this message]
2018-05-29 12:47   ` [PATCH 02/10] nvme: ANA transition timeout handling Christoph Hellwig
2018-05-29 13:34     ` Hannes Reinecke
2018-05-29 13:47       ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 03/10] nvme: Only update capacity for optimized or non-optimized paths Hannes Reinecke
2018-05-29 12:38   ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 04/10] nvme: clear current path on ANA state change Hannes Reinecke
2018-05-29 12:22   ` Johannes Thumshirn
2018-05-29 12:43     ` Hannes Reinecke
2018-05-29 12:48   ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 05/10] nvme: retry nvme_get_log_ext() when processing ANA log Hannes Reinecke
2018-05-29 12:48   ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 06/10] nvme: simplify check for ANA in nvme_ns_id_attrs_are_visible() Hannes Reinecke
2018-05-29 12:49   ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 07/10] nvmet: make ANATT configurable Hannes Reinecke
2018-05-29 12:50   ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 08/10] nvmet: Set nanagrpid correctly Hannes Reinecke
2018-05-29 12:51   ` Christoph Hellwig
2018-05-29 13:04     ` Hannes Reinecke
2018-05-29 13:38       ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 09/10] nvmet: Set mnan correctly Hannes Reinecke
2018-05-29 12:52   ` Christoph Hellwig
2018-05-29 13:06     ` Hannes Reinecke
2018-05-29 13:40       ` Christoph Hellwig
2018-05-29 10:14 ` [PATCH 10/10] nvmet: set 'nuse' and 'nsze' to zero for inaccessible paths Hannes Reinecke
2018-05-29 12:57   ` Christoph Hellwig
2018-05-31 10:30 ` [PATCH 00/10] nvme: ANA fixups Sagi Grimberg
2018-05-31 16:26   ` Christoph Hellwig

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=20180529101431.62271-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).