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
next prev 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 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.