From: Christoph Hellwig <hch@lst.de>
To: Daniel Verkamp <daniel.verkamp@intel.com>
Cc: Christoph Hellwig <hch@lst.de>,
linux-nvme@lists.infradead.org, Jens Axboe <axboe@kernel.dk>,
Keith Busch <keith.busch@intel.com>,
linux-block@vger.kernel.org, Sagi Grimberg <sagi@grimberg.me>,
Hannes Reinecke <hare@suse.de>
Subject: Re: [PATCH 06/12] nvmet: implement the changed namespaces log
Date: Thu, 31 May 2018 18:25:14 +0200 [thread overview]
Message-ID: <20180531162514.GA30839@lst.de> (raw)
In-Reply-To: <0c4cc53d-1c28-0bf5-d454-df6c9ef9335b@intel.com>
On Wed, May 30, 2018 at 10:33:49AM -0700, Daniel Verkamp wrote:
> Minor nitpick here: if ctrlr->nr_changed_ns is exactly
> NVME_MAX_CHANGED_NAMESPACES and the new nsid is already in the list,
> this will skip down to the 0xffffffff case below, even though it could
> have just left the list as-is.
>
> I don't know if this is a problem in practice; reporting 0xffffffff is
> probably always safe, since the host will presumably treat that as
> "rescan everything".
It probably doesn't matter, but it turns doing this propely actually
looks cleaner as well:
---
>From d4baf4068220a90ecf67309d01ece5d0aadd952e Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Fri, 25 May 2018 17:16:09 +0200
Subject: nvmet: implement the changed namespaces log
Just keep a per-controller buffer of changed namespaces and copy it out
in the get log page implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/nvme/target/admin-cmd.c | 26 +++++++++++++++
drivers/nvme/target/core.c | 56 +++++++++++++++++++++++++++------
drivers/nvme/target/nvmet.h | 3 ++
3 files changed, 76 insertions(+), 9 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 25b4e4ea69c8..7677b7b188ea 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -126,6 +126,29 @@ static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
nvmet_req_complete(req, status);
}
+static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
+{
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ u16 status = NVME_SC_INTERNAL;
+ size_t len;
+
+ if (req->data_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
+ goto out;
+
+ mutex_lock(&ctrl->lock);
+ if (ctrl->nr_changed_ns == U32_MAX)
+ len = sizeof(__le32);
+ else
+ len = ctrl->nr_changed_ns * sizeof(__le32);
+ status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
+ if (!status)
+ status = nvmet_zero_sgl(req, len, req->data_len - len);
+ ctrl->nr_changed_ns = 0;
+ mutex_unlock(&ctrl->lock);
+out:
+ nvmet_req_complete(req, status);
+}
+
static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -546,6 +569,9 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
*/
req->execute = nvmet_execute_get_log_page_noop;
return 0;
+ case NVME_LOG_CHANGED_NS:
+ req->execute = nvmet_execute_get_log_changed_ns;
+ return 0;
}
break;
case nvme_admin_identify:
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 55c4bc693aa2..4fe88e15c641 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -144,6 +144,42 @@ static void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
schedule_work(&ctrl->async_event_work);
}
+static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
+{
+ u32 i;
+
+ mutex_lock(&ctrl->lock);
+ if (ctrl->nr_changed_ns > NVME_MAX_CHANGED_NAMESPACES)
+ goto out_unlock;
+
+ for (i = 0; i < ctrl->nr_changed_ns; i++) {
+ if (ctrl->changed_ns_list[i] == nsid)
+ goto out_unlock;
+ }
+
+ if (ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES) {
+ ctrl->changed_ns_list[0] = cpu_to_le32(0xffffffff);
+ ctrl->nr_changed_ns = U32_MAX;
+ goto out_unlock;
+ }
+
+ ctrl->changed_ns_list[ctrl->nr_changed_ns++] = nsid;
+out_unlock:
+ mutex_unlock(&ctrl->lock);
+}
+
+static void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)
+{
+ struct nvmet_ctrl *ctrl;
+
+ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
+ nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid));
+ nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE,
+ NVME_AER_NOTICE_NS_CHANGED,
+ NVME_LOG_CHANGED_NS);
+ }
+}
+
int nvmet_register_transport(const struct nvmet_fabrics_ops *ops)
{
int ret = 0;
@@ -287,7 +323,6 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns)
int nvmet_ns_enable(struct nvmet_ns *ns)
{
struct nvmet_subsys *subsys = ns->subsys;
- struct nvmet_ctrl *ctrl;
int ret = 0;
mutex_lock(&subsys->lock);
@@ -326,9 +361,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
list_add_tail_rcu(&ns->dev_link, &old->dev_link);
}
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
-
+ nvmet_ns_changed(subsys, ns->nsid);
ns->enabled = true;
ret = 0;
out_unlock:
@@ -342,7 +375,6 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
void nvmet_ns_disable(struct nvmet_ns *ns)
{
struct nvmet_subsys *subsys = ns->subsys;
- struct nvmet_ctrl *ctrl;
mutex_lock(&subsys->lock);
if (!ns->enabled)
@@ -368,9 +400,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
percpu_ref_exit(&ns->ref);
mutex_lock(&subsys->lock);
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
-
+ nvmet_ns_changed(subsys, ns->nsid);
nvmet_ns_dev_disable(ns);
out_unlock:
mutex_unlock(&subsys->lock);
@@ -832,11 +862,16 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
kref_init(&ctrl->ref);
ctrl->subsys = subsys;
+ ctrl->changed_ns_list = kmalloc_array(NVME_MAX_CHANGED_NAMESPACES,
+ sizeof(__le32), GFP_KERNEL);
+ if (!ctrl->changed_ns_list)
+ goto out_free_ctrl;
+
ctrl->cqs = kcalloc(subsys->max_qid + 1,
sizeof(struct nvmet_cq *),
GFP_KERNEL);
if (!ctrl->cqs)
- goto out_free_ctrl;
+ goto out_free_changed_ns_list;
ctrl->sqs = kcalloc(subsys->max_qid + 1,
sizeof(struct nvmet_sq *),
@@ -894,6 +929,8 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
kfree(ctrl->sqs);
out_free_cqs:
kfree(ctrl->cqs);
+out_free_changed_ns_list:
+ kfree(ctrl->changed_ns_list);
out_free_ctrl:
kfree(ctrl);
out_put_subsystem:
@@ -920,6 +957,7 @@ static void nvmet_ctrl_free(struct kref *ref)
kfree(ctrl->sqs);
kfree(ctrl->cqs);
+ kfree(ctrl->changed_ns_list);
kfree(ctrl);
nvmet_subsys_put(subsys);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 768abe203298..8cdc1e550396 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -135,6 +135,9 @@ struct nvmet_ctrl {
const struct nvmet_fabrics_ops *ops;
+ __le32 *changed_ns_list;
+ u32 nr_changed_ns;
+
char subsysnqn[NVMF_NQN_FIELD_LEN];
char hostnqn[NVMF_NQN_FIELD_LEN];
};
--
2.17.0
WARNING: multiple messages have this Message-ID (diff)
From: hch@lst.de (Christoph Hellwig)
Subject: [PATCH 06/12] nvmet: implement the changed namespaces log
Date: Thu, 31 May 2018 18:25:14 +0200 [thread overview]
Message-ID: <20180531162514.GA30839@lst.de> (raw)
In-Reply-To: <0c4cc53d-1c28-0bf5-d454-df6c9ef9335b@intel.com>
On Wed, May 30, 2018@10:33:49AM -0700, Daniel Verkamp wrote:
> Minor nitpick here: if ctrlr->nr_changed_ns is exactly
> NVME_MAX_CHANGED_NAMESPACES and the new nsid is already in the list,
> this will skip down to the 0xffffffff case below, even though it could
> have just left the list as-is.
>
> I don't know if this is a problem in practice; reporting 0xffffffff is
> probably always safe, since the host will presumably treat that as
> "rescan everything".
It probably doesn't matter, but it turns doing this propely actually
looks cleaner as well:
---
>From d4baf4068220a90ecf67309d01ece5d0aadd952e Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Fri, 25 May 2018 17:16:09 +0200
Subject: nvmet: implement the changed namespaces log
Just keep a per-controller buffer of changed namespaces and copy it out
in the get log page implementation.
Signed-off-by: Christoph Hellwig <hch at lst.de>
---
drivers/nvme/target/admin-cmd.c | 26 +++++++++++++++
drivers/nvme/target/core.c | 56 +++++++++++++++++++++++++++------
drivers/nvme/target/nvmet.h | 3 ++
3 files changed, 76 insertions(+), 9 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 25b4e4ea69c8..7677b7b188ea 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -126,6 +126,29 @@ static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
nvmet_req_complete(req, status);
}
+static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
+{
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ u16 status = NVME_SC_INTERNAL;
+ size_t len;
+
+ if (req->data_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
+ goto out;
+
+ mutex_lock(&ctrl->lock);
+ if (ctrl->nr_changed_ns == U32_MAX)
+ len = sizeof(__le32);
+ else
+ len = ctrl->nr_changed_ns * sizeof(__le32);
+ status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
+ if (!status)
+ status = nvmet_zero_sgl(req, len, req->data_len - len);
+ ctrl->nr_changed_ns = 0;
+ mutex_unlock(&ctrl->lock);
+out:
+ nvmet_req_complete(req, status);
+}
+
static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -546,6 +569,9 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
*/
req->execute = nvmet_execute_get_log_page_noop;
return 0;
+ case NVME_LOG_CHANGED_NS:
+ req->execute = nvmet_execute_get_log_changed_ns;
+ return 0;
}
break;
case nvme_admin_identify:
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 55c4bc693aa2..4fe88e15c641 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -144,6 +144,42 @@ static void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
schedule_work(&ctrl->async_event_work);
}
+static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
+{
+ u32 i;
+
+ mutex_lock(&ctrl->lock);
+ if (ctrl->nr_changed_ns > NVME_MAX_CHANGED_NAMESPACES)
+ goto out_unlock;
+
+ for (i = 0; i < ctrl->nr_changed_ns; i++) {
+ if (ctrl->changed_ns_list[i] == nsid)
+ goto out_unlock;
+ }
+
+ if (ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES) {
+ ctrl->changed_ns_list[0] = cpu_to_le32(0xffffffff);
+ ctrl->nr_changed_ns = U32_MAX;
+ goto out_unlock;
+ }
+
+ ctrl->changed_ns_list[ctrl->nr_changed_ns++] = nsid;
+out_unlock:
+ mutex_unlock(&ctrl->lock);
+}
+
+static void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)
+{
+ struct nvmet_ctrl *ctrl;
+
+ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
+ nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid));
+ nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE,
+ NVME_AER_NOTICE_NS_CHANGED,
+ NVME_LOG_CHANGED_NS);
+ }
+}
+
int nvmet_register_transport(const struct nvmet_fabrics_ops *ops)
{
int ret = 0;
@@ -287,7 +323,6 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns)
int nvmet_ns_enable(struct nvmet_ns *ns)
{
struct nvmet_subsys *subsys = ns->subsys;
- struct nvmet_ctrl *ctrl;
int ret = 0;
mutex_lock(&subsys->lock);
@@ -326,9 +361,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
list_add_tail_rcu(&ns->dev_link, &old->dev_link);
}
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
-
+ nvmet_ns_changed(subsys, ns->nsid);
ns->enabled = true;
ret = 0;
out_unlock:
@@ -342,7 +375,6 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
void nvmet_ns_disable(struct nvmet_ns *ns)
{
struct nvmet_subsys *subsys = ns->subsys;
- struct nvmet_ctrl *ctrl;
mutex_lock(&subsys->lock);
if (!ns->enabled)
@@ -368,9 +400,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
percpu_ref_exit(&ns->ref);
mutex_lock(&subsys->lock);
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
-
+ nvmet_ns_changed(subsys, ns->nsid);
nvmet_ns_dev_disable(ns);
out_unlock:
mutex_unlock(&subsys->lock);
@@ -832,11 +862,16 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
kref_init(&ctrl->ref);
ctrl->subsys = subsys;
+ ctrl->changed_ns_list = kmalloc_array(NVME_MAX_CHANGED_NAMESPACES,
+ sizeof(__le32), GFP_KERNEL);
+ if (!ctrl->changed_ns_list)
+ goto out_free_ctrl;
+
ctrl->cqs = kcalloc(subsys->max_qid + 1,
sizeof(struct nvmet_cq *),
GFP_KERNEL);
if (!ctrl->cqs)
- goto out_free_ctrl;
+ goto out_free_changed_ns_list;
ctrl->sqs = kcalloc(subsys->max_qid + 1,
sizeof(struct nvmet_sq *),
@@ -894,6 +929,8 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
kfree(ctrl->sqs);
out_free_cqs:
kfree(ctrl->cqs);
+out_free_changed_ns_list:
+ kfree(ctrl->changed_ns_list);
out_free_ctrl:
kfree(ctrl);
out_put_subsystem:
@@ -920,6 +957,7 @@ static void nvmet_ctrl_free(struct kref *ref)
kfree(ctrl->sqs);
kfree(ctrl->cqs);
+ kfree(ctrl->changed_ns_list);
kfree(ctrl);
nvmet_subsys_put(subsys);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 768abe203298..8cdc1e550396 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -135,6 +135,9 @@ struct nvmet_ctrl {
const struct nvmet_fabrics_ops *ops;
+ __le32 *changed_ns_list;
+ u32 nr_changed_ns;
+
char subsysnqn[NVMF_NQN_FIELD_LEN];
char hostnqn[NVMF_NQN_FIELD_LEN];
};
--
2.17.0
next prev parent reply other threads:[~2018-05-31 16:25 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-30 16:45 nvme/nvmet AEN and log page fixups v2 Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 16:45 ` [PATCH 01/12] nvme.h: untangle AEN notice definitions Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:21 ` Sagi Grimberg
2018-05-30 21:21 ` Sagi Grimberg
2018-06-04 6:13 ` Hannes Reinecke
2018-06-04 6:13 ` Hannes Reinecke
2018-06-04 6:13 ` Hannes Reinecke
2018-06-04 6:13 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 02/12] nvme.h: add the changed namespace list log Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:22 ` Sagi Grimberg
2018-05-30 21:22 ` Sagi Grimberg
2018-06-04 6:13 ` Hannes Reinecke
2018-06-04 6:13 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 03/12] nvme.h: add AER configuration symbols Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:23 ` Sagi Grimberg
2018-05-30 21:23 ` Sagi Grimberg
2018-05-30 16:45 ` [PATCH 04/12] nvmet: add a new nvmet_zero_sgl helper Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:24 ` Sagi Grimberg
2018-05-30 21:24 ` Sagi Grimberg
2018-06-04 6:14 ` Hannes Reinecke
2018-06-04 6:14 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 05/12] nvmet: split log page implementation Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:25 ` Sagi Grimberg
2018-05-30 21:25 ` Sagi Grimberg
2018-06-04 6:14 ` Hannes Reinecke
2018-06-04 6:14 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 06/12] nvmet: implement the changed namespaces log Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 17:33 ` Daniel Verkamp
2018-05-30 17:33 ` Daniel Verkamp
2018-05-31 16:25 ` Christoph Hellwig [this message]
2018-05-31 16:25 ` Christoph Hellwig
2018-05-31 16:36 ` Daniel Verkamp
2018-05-31 16:36 ` Daniel Verkamp
2018-05-30 21:28 ` Sagi Grimberg
2018-05-30 21:28 ` Sagi Grimberg
2018-06-04 6:15 ` Hannes Reinecke
2018-06-04 6:15 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 07/12] nvmet: Add AEN configuration support Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:30 ` Sagi Grimberg
2018-05-30 21:30 ` Sagi Grimberg
2018-05-30 16:45 ` [PATCH 08/12] nvmet: mask pending AERs Christoph Hellwig
2018-05-30 21:31 ` Sagi Grimberg
2018-06-04 6:15 ` Hannes Reinecke
2018-06-12 15:41 ` Israel Rukshin
2018-06-13 7:42 ` Christoph Hellwig
2018-06-13 8:23 ` Max Gurtovoy
2018-06-13 11:26 ` Christoph Hellwig
2018-06-19 14:03 ` Sagi Grimberg
2018-05-30 16:45 ` [PATCH 09/12] nvme: submit AEN event configuration on startup Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:31 ` Sagi Grimberg
2018-05-30 21:31 ` Sagi Grimberg
2018-05-30 16:45 ` [PATCH 10/12] nvme: mark nvme_queue_scan static Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:31 ` Sagi Grimberg
2018-05-30 21:31 ` Sagi Grimberg
2018-06-04 6:16 ` Hannes Reinecke
2018-06-04 6:16 ` Hannes Reinecke
2018-05-30 16:45 ` [PATCH 11/12] nvme: use the changed namespaces list log to clear ns data changed AENs Christoph Hellwig
2018-05-30 16:45 ` Christoph Hellwig
2018-05-30 21:34 ` Sagi Grimberg
2018-05-30 21:34 ` Sagi Grimberg
2018-06-04 6:16 ` Hannes Reinecke
2018-06-04 6:16 ` Hannes Reinecke
2018-05-30 16:46 ` [PATCH 12/12] nvme: limit warnings from nvme_identify_ns Christoph Hellwig
2018-05-30 16:46 ` Christoph Hellwig
2018-05-30 21:35 ` Sagi Grimberg
2018-05-30 21:35 ` Sagi Grimberg
2018-06-04 6:17 ` Hannes Reinecke
2018-06-04 6:17 ` Hannes Reinecke
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=20180531162514.GA30839@lst.de \
--to=hch@lst.de \
--cc=axboe@kernel.dk \
--cc=daniel.verkamp@intel.com \
--cc=hare@suse.de \
--cc=keith.busch@intel.com \
--cc=linux-block@vger.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.