From: Mike Snitzer <snitzer@redhat.com>
To: Hannes Reinecke <hare@suse.de>
Cc: Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, dm-devel@redhat.com,
Christoph Hellwig <hch@lst.de>,
linux-nvme@lists.infradead.org
Subject: Re: [dm-devel] [PATCH v2 3/4] nvme: introduce FAILUP handling for REQ_FAILFAST_TRANSPORT
Date: Fri, 16 Apr 2021 11:03:01 -0400 [thread overview]
Message-ID: <20210416150301.GC16047@redhat.com> (raw)
In-Reply-To: <6185100e-89e6-0a7f-8901-9ce86fe8f1ac@suse.de>
On Fri, Apr 16 2021 at 10:07am -0400,
Hannes Reinecke <hare@suse.de> wrote:
> On 4/16/21 1:15 AM, Mike Snitzer wrote:
> > If REQ_FAILFAST_TRANSPORT is set it means the driver should not retry
> > IO that completed with transport errors. REQ_FAILFAST_TRANSPORT is
> > set by multipathing software (e.g. dm-multipath) before it issues IO.
> >
> > Update NVMe to allow failover of requests marked with either
> > REQ_NVME_MPATH or REQ_FAILFAST_TRANSPORT. This allows such requests
> > to be given a disposition of either FAILOVER or FAILUP respectively.
> > FAILUP handling ensures a retryable error is returned up from NVMe.
> >
> > Introduce nvme_failup_req() for use in nvme_complete_rq() if
> > nvme_decide_disposition() returns FAILUP. nvme_failup_req() ensures
> > the request is completed with a retryable IO error when appropriate.
> > __nvme_end_req() was factored out for use by both nvme_end_req() and
> > nvme_failup_req().
> >
> > Signed-off-by: Mike Snitzer <snitzer@redhat.com>
> > ---
> > drivers/nvme/host/core.c | 31 ++++++++++++++++++++++++++-----
> > 1 file changed, 26 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> > index 4134cf3c7e48..10375197dd53 100644
> > --- a/drivers/nvme/host/core.c
> > +++ b/drivers/nvme/host/core.c
> > @@ -299,6 +299,7 @@ enum nvme_disposition {
> > COMPLETE,
> > RETRY,
> > FAILOVER,
> > + FAILUP,
> > };
> >
> > static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > @@ -318,10 +319,11 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > nvme_req(req)->retries >= nvme_max_retries)
> > return COMPLETE;
> >
> > - if (req->cmd_flags & REQ_NVME_MPATH) {
> > + if (req->cmd_flags & (REQ_NVME_MPATH | REQ_FAILFAST_TRANSPORT)) {
> > if (nvme_is_path_error(nvme_req(req)->status) ||
> > blk_queue_dying(req->q))
> > - return FAILOVER;
> > + return (req->cmd_flags & REQ_NVME_MPATH) ?
> > + FAILOVER : FAILUP;
> > } else {
> > if (blk_queue_dying(req->q))
> > return COMPLETE;
> > @@ -330,10 +332,8 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > return RETRY;
> > }
> >
> > -static inline void nvme_end_req(struct request *req)
> > +static inline void __nvme_end_req(struct request *req, blk_status_t status)
> > {
> > - blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > -
> > if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
> > req_op(req) == REQ_OP_ZONE_APPEND)
> > req->__sector = nvme_lba_to_sect(req->q->queuedata,
> > @@ -343,6 +343,24 @@ static inline void nvme_end_req(struct request *req)
> > blk_mq_end_request(req, status);
> > }
> >
> > +static inline void nvme_end_req(struct request *req)
> > +{
> > + __nvme_end_req(req, nvme_error_status(nvme_req(req)->status));
> > +}
> > +
> > +static void nvme_failup_req(struct request *req)
> > +{
> > + blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > +
> > + if (WARN_ON_ONCE(!blk_path_error(status))) {
> > + pr_debug("Request meant for failover but blk_status_t (errno=%d) was not retryable.\n",
> > + blk_status_to_errno(status));
> > + status = BLK_STS_IOERR;
> > + }
> > +
> > + __nvme_end_req(req, status);
> > +}
> > +
> > void nvme_complete_rq(struct request *req)
> > {
> > trace_nvme_complete_rq(req);
> > @@ -361,6 +379,9 @@ void nvme_complete_rq(struct request *req)
> > case FAILOVER:
> > nvme_failover_req(req);
> > return;
> > + case FAILUP:
> > + nvme_failup_req(req);
> > + return;
> > }
> > }
> > EXPORT_SYMBOL_GPL(nvme_complete_rq);
> >
>
> Hmm. Quite convoluted, methinks.
Maybe you didn't read the header or patch?
I'm cool with critical review when it is clear the reviewer fully
understands the patch but... ;)
> Shouldn't this achieve the same thing?
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index e89ec2522ca6..8c36a2196b66 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -303,8 +303,10 @@ static inline enum nvme_disposition
> nvme_decide_disposition(struct request *req)
> if (likely(nvme_req(req)->status == 0))
> return COMPLETE;
>
> - if (blk_noretry_request(req) ||
> - (nvme_req(req)->status & NVME_SC_DNR) ||
> + if (blk_noretry_request(req))
> + nvme_req(req)->status |= NVME_SC_DNR;
> +
> + if ((nvme_req(req)->status & NVME_SC_DNR) ||
> nvme_req(req)->retries >= nvme_max_retries)
> return COMPLETE;
Definitely won't achieve the same. And especially not with patch 1/4
("nvme: return BLK_STS_DO_NOT_RETRY if the DNR bit is set") that you
gave your Reviewed-by to earlier.
Instead of "FAILUP", I thought about using "FAILUP_AND_OVER" to convey
that this is a variant of failover. Meaning it takes the same patch as
nvme "FAILOVER" until the very end; where it does REQ_FAILFAST_TRANSPORT
specific work detailed in nvme_failup_req().
And then patch 4/4 makes further use of nvme_failup_req() by adding a
call to the factored out nvme_update_ana().
Mike
--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
WARNING: multiple messages have this Message-ID (diff)
From: Mike Snitzer <snitzer@redhat.com>
To: Hannes Reinecke <hare@suse.de>
Cc: Christoph Hellwig <hch@lst.de>, Jens Axboe <axboe@kernel.dk>,
dm-devel@redhat.com, linux-block@vger.kernel.org,
linux-nvme@lists.infradead.org
Subject: Re: [PATCH v2 3/4] nvme: introduce FAILUP handling for REQ_FAILFAST_TRANSPORT
Date: Fri, 16 Apr 2021 11:03:01 -0400 [thread overview]
Message-ID: <20210416150301.GC16047@redhat.com> (raw)
In-Reply-To: <6185100e-89e6-0a7f-8901-9ce86fe8f1ac@suse.de>
On Fri, Apr 16 2021 at 10:07am -0400,
Hannes Reinecke <hare@suse.de> wrote:
> On 4/16/21 1:15 AM, Mike Snitzer wrote:
> > If REQ_FAILFAST_TRANSPORT is set it means the driver should not retry
> > IO that completed with transport errors. REQ_FAILFAST_TRANSPORT is
> > set by multipathing software (e.g. dm-multipath) before it issues IO.
> >
> > Update NVMe to allow failover of requests marked with either
> > REQ_NVME_MPATH or REQ_FAILFAST_TRANSPORT. This allows such requests
> > to be given a disposition of either FAILOVER or FAILUP respectively.
> > FAILUP handling ensures a retryable error is returned up from NVMe.
> >
> > Introduce nvme_failup_req() for use in nvme_complete_rq() if
> > nvme_decide_disposition() returns FAILUP. nvme_failup_req() ensures
> > the request is completed with a retryable IO error when appropriate.
> > __nvme_end_req() was factored out for use by both nvme_end_req() and
> > nvme_failup_req().
> >
> > Signed-off-by: Mike Snitzer <snitzer@redhat.com>
> > ---
> > drivers/nvme/host/core.c | 31 ++++++++++++++++++++++++++-----
> > 1 file changed, 26 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> > index 4134cf3c7e48..10375197dd53 100644
> > --- a/drivers/nvme/host/core.c
> > +++ b/drivers/nvme/host/core.c
> > @@ -299,6 +299,7 @@ enum nvme_disposition {
> > COMPLETE,
> > RETRY,
> > FAILOVER,
> > + FAILUP,
> > };
> >
> > static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > @@ -318,10 +319,11 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > nvme_req(req)->retries >= nvme_max_retries)
> > return COMPLETE;
> >
> > - if (req->cmd_flags & REQ_NVME_MPATH) {
> > + if (req->cmd_flags & (REQ_NVME_MPATH | REQ_FAILFAST_TRANSPORT)) {
> > if (nvme_is_path_error(nvme_req(req)->status) ||
> > blk_queue_dying(req->q))
> > - return FAILOVER;
> > + return (req->cmd_flags & REQ_NVME_MPATH) ?
> > + FAILOVER : FAILUP;
> > } else {
> > if (blk_queue_dying(req->q))
> > return COMPLETE;
> > @@ -330,10 +332,8 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > return RETRY;
> > }
> >
> > -static inline void nvme_end_req(struct request *req)
> > +static inline void __nvme_end_req(struct request *req, blk_status_t status)
> > {
> > - blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > -
> > if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
> > req_op(req) == REQ_OP_ZONE_APPEND)
> > req->__sector = nvme_lba_to_sect(req->q->queuedata,
> > @@ -343,6 +343,24 @@ static inline void nvme_end_req(struct request *req)
> > blk_mq_end_request(req, status);
> > }
> >
> > +static inline void nvme_end_req(struct request *req)
> > +{
> > + __nvme_end_req(req, nvme_error_status(nvme_req(req)->status));
> > +}
> > +
> > +static void nvme_failup_req(struct request *req)
> > +{
> > + blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > +
> > + if (WARN_ON_ONCE(!blk_path_error(status))) {
> > + pr_debug("Request meant for failover but blk_status_t (errno=%d) was not retryable.\n",
> > + blk_status_to_errno(status));
> > + status = BLK_STS_IOERR;
> > + }
> > +
> > + __nvme_end_req(req, status);
> > +}
> > +
> > void nvme_complete_rq(struct request *req)
> > {
> > trace_nvme_complete_rq(req);
> > @@ -361,6 +379,9 @@ void nvme_complete_rq(struct request *req)
> > case FAILOVER:
> > nvme_failover_req(req);
> > return;
> > + case FAILUP:
> > + nvme_failup_req(req);
> > + return;
> > }
> > }
> > EXPORT_SYMBOL_GPL(nvme_complete_rq);
> >
>
> Hmm. Quite convoluted, methinks.
Maybe you didn't read the header or patch?
I'm cool with critical review when it is clear the reviewer fully
understands the patch but... ;)
> Shouldn't this achieve the same thing?
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index e89ec2522ca6..8c36a2196b66 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -303,8 +303,10 @@ static inline enum nvme_disposition
> nvme_decide_disposition(struct request *req)
> if (likely(nvme_req(req)->status == 0))
> return COMPLETE;
>
> - if (blk_noretry_request(req) ||
> - (nvme_req(req)->status & NVME_SC_DNR) ||
> + if (blk_noretry_request(req))
> + nvme_req(req)->status |= NVME_SC_DNR;
> +
> + if ((nvme_req(req)->status & NVME_SC_DNR) ||
> nvme_req(req)->retries >= nvme_max_retries)
> return COMPLETE;
Definitely won't achieve the same. And especially not with patch 1/4
("nvme: return BLK_STS_DO_NOT_RETRY if the DNR bit is set") that you
gave your Reviewed-by to earlier.
Instead of "FAILUP", I thought about using "FAILUP_AND_OVER" to convey
that this is a variant of failover. Meaning it takes the same patch as
nvme "FAILOVER" until the very end; where it does REQ_FAILFAST_TRANSPORT
specific work detailed in nvme_failup_req().
And then patch 4/4 makes further use of nvme_failup_req() by adding a
call to the factored out nvme_update_ana().
Mike
WARNING: multiple messages have this Message-ID (diff)
From: Mike Snitzer <snitzer@redhat.com>
To: Hannes Reinecke <hare@suse.de>
Cc: Christoph Hellwig <hch@lst.de>, Jens Axboe <axboe@kernel.dk>,
dm-devel@redhat.com, linux-block@vger.kernel.org,
linux-nvme@lists.infradead.org
Subject: Re: [PATCH v2 3/4] nvme: introduce FAILUP handling for REQ_FAILFAST_TRANSPORT
Date: Fri, 16 Apr 2021 11:03:01 -0400 [thread overview]
Message-ID: <20210416150301.GC16047@redhat.com> (raw)
In-Reply-To: <6185100e-89e6-0a7f-8901-9ce86fe8f1ac@suse.de>
On Fri, Apr 16 2021 at 10:07am -0400,
Hannes Reinecke <hare@suse.de> wrote:
> On 4/16/21 1:15 AM, Mike Snitzer wrote:
> > If REQ_FAILFAST_TRANSPORT is set it means the driver should not retry
> > IO that completed with transport errors. REQ_FAILFAST_TRANSPORT is
> > set by multipathing software (e.g. dm-multipath) before it issues IO.
> >
> > Update NVMe to allow failover of requests marked with either
> > REQ_NVME_MPATH or REQ_FAILFAST_TRANSPORT. This allows such requests
> > to be given a disposition of either FAILOVER or FAILUP respectively.
> > FAILUP handling ensures a retryable error is returned up from NVMe.
> >
> > Introduce nvme_failup_req() for use in nvme_complete_rq() if
> > nvme_decide_disposition() returns FAILUP. nvme_failup_req() ensures
> > the request is completed with a retryable IO error when appropriate.
> > __nvme_end_req() was factored out for use by both nvme_end_req() and
> > nvme_failup_req().
> >
> > Signed-off-by: Mike Snitzer <snitzer@redhat.com>
> > ---
> > drivers/nvme/host/core.c | 31 ++++++++++++++++++++++++++-----
> > 1 file changed, 26 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> > index 4134cf3c7e48..10375197dd53 100644
> > --- a/drivers/nvme/host/core.c
> > +++ b/drivers/nvme/host/core.c
> > @@ -299,6 +299,7 @@ enum nvme_disposition {
> > COMPLETE,
> > RETRY,
> > FAILOVER,
> > + FAILUP,
> > };
> >
> > static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > @@ -318,10 +319,11 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > nvme_req(req)->retries >= nvme_max_retries)
> > return COMPLETE;
> >
> > - if (req->cmd_flags & REQ_NVME_MPATH) {
> > + if (req->cmd_flags & (REQ_NVME_MPATH | REQ_FAILFAST_TRANSPORT)) {
> > if (nvme_is_path_error(nvme_req(req)->status) ||
> > blk_queue_dying(req->q))
> > - return FAILOVER;
> > + return (req->cmd_flags & REQ_NVME_MPATH) ?
> > + FAILOVER : FAILUP;
> > } else {
> > if (blk_queue_dying(req->q))
> > return COMPLETE;
> > @@ -330,10 +332,8 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
> > return RETRY;
> > }
> >
> > -static inline void nvme_end_req(struct request *req)
> > +static inline void __nvme_end_req(struct request *req, blk_status_t status)
> > {
> > - blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > -
> > if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
> > req_op(req) == REQ_OP_ZONE_APPEND)
> > req->__sector = nvme_lba_to_sect(req->q->queuedata,
> > @@ -343,6 +343,24 @@ static inline void nvme_end_req(struct request *req)
> > blk_mq_end_request(req, status);
> > }
> >
> > +static inline void nvme_end_req(struct request *req)
> > +{
> > + __nvme_end_req(req, nvme_error_status(nvme_req(req)->status));
> > +}
> > +
> > +static void nvme_failup_req(struct request *req)
> > +{
> > + blk_status_t status = nvme_error_status(nvme_req(req)->status);
> > +
> > + if (WARN_ON_ONCE(!blk_path_error(status))) {
> > + pr_debug("Request meant for failover but blk_status_t (errno=%d) was not retryable.\n",
> > + blk_status_to_errno(status));
> > + status = BLK_STS_IOERR;
> > + }
> > +
> > + __nvme_end_req(req, status);
> > +}
> > +
> > void nvme_complete_rq(struct request *req)
> > {
> > trace_nvme_complete_rq(req);
> > @@ -361,6 +379,9 @@ void nvme_complete_rq(struct request *req)
> > case FAILOVER:
> > nvme_failover_req(req);
> > return;
> > + case FAILUP:
> > + nvme_failup_req(req);
> > + return;
> > }
> > }
> > EXPORT_SYMBOL_GPL(nvme_complete_rq);
> >
>
> Hmm. Quite convoluted, methinks.
Maybe you didn't read the header or patch?
I'm cool with critical review when it is clear the reviewer fully
understands the patch but... ;)
> Shouldn't this achieve the same thing?
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index e89ec2522ca6..8c36a2196b66 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -303,8 +303,10 @@ static inline enum nvme_disposition
> nvme_decide_disposition(struct request *req)
> if (likely(nvme_req(req)->status == 0))
> return COMPLETE;
>
> - if (blk_noretry_request(req) ||
> - (nvme_req(req)->status & NVME_SC_DNR) ||
> + if (blk_noretry_request(req))
> + nvme_req(req)->status |= NVME_SC_DNR;
> +
> + if ((nvme_req(req)->status & NVME_SC_DNR) ||
> nvme_req(req)->retries >= nvme_max_retries)
> return COMPLETE;
Definitely won't achieve the same. And especially not with patch 1/4
("nvme: return BLK_STS_DO_NOT_RETRY if the DNR bit is set") that you
gave your Reviewed-by to earlier.
Instead of "FAILUP", I thought about using "FAILUP_AND_OVER" to convey
that this is a variant of failover. Meaning it takes the same patch as
nvme "FAILOVER" until the very end; where it does REQ_FAILFAST_TRANSPORT
specific work detailed in nvme_failup_req().
And then patch 4/4 makes further use of nvme_failup_req() by adding a
call to the factored out nvme_update_ana().
Mike
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2021-04-16 15:04 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-15 23:15 [dm-devel] [PATCH v2 0/4] nvme: improve error handling and ana_state to work well with dm-multipath Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` [dm-devel] [PATCH v2 1/4] nvme: return BLK_STS_DO_NOT_RETRY if the DNR bit is set Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:48 ` [dm-devel] " Chaitanya Kulkarni
2021-04-15 23:48 ` Chaitanya Kulkarni
2021-04-15 23:48 ` Chaitanya Kulkarni
2021-04-16 13:51 ` [dm-devel] " Hannes Reinecke
2021-04-16 13:51 ` Hannes Reinecke
2021-04-16 13:51 ` Hannes Reinecke
2021-04-15 23:15 ` [dm-devel] [PATCH v2 2/4] nvme: allow local retry for requests with REQ_FAILFAST_TRANSPORT set Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-16 14:01 ` [dm-devel] " Hannes Reinecke
2021-04-16 14:01 ` Hannes Reinecke
2021-04-16 14:01 ` Hannes Reinecke
2021-04-16 14:53 ` [dm-devel] " Mike Snitzer
2021-04-16 14:53 ` Mike Snitzer
2021-04-16 14:53 ` Mike Snitzer
2021-04-16 15:20 ` [dm-devel] " Hannes Reinecke
2021-04-16 15:20 ` Hannes Reinecke
2021-04-16 15:20 ` Hannes Reinecke
2021-04-16 15:32 ` [dm-devel] " Mike Snitzer
2021-04-16 15:32 ` Mike Snitzer
2021-04-16 15:32 ` Mike Snitzer
2021-04-15 23:15 ` [dm-devel] [PATCH v2 3/4] nvme: introduce FAILUP handling for REQ_FAILFAST_TRANSPORT Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-16 14:07 ` [dm-devel] " Hannes Reinecke
2021-04-16 14:07 ` Hannes Reinecke
2021-04-16 14:07 ` Hannes Reinecke
2021-04-16 15:03 ` Mike Snitzer [this message]
2021-04-16 15:03 ` Mike Snitzer
2021-04-16 15:03 ` Mike Snitzer
2021-04-16 16:23 ` [dm-devel] " Hannes Reinecke
2021-04-16 16:23 ` Hannes Reinecke
2021-04-16 16:23 ` Hannes Reinecke
2021-04-16 20:03 ` [dm-devel] " Ewan D. Milne
2021-04-16 20:03 ` Ewan D. Milne
2021-04-16 20:03 ` Ewan D. Milne
2021-04-16 20:52 ` Ewan D. Milne
2021-04-16 20:52 ` Ewan D. Milne
2021-04-16 20:52 ` Ewan D. Milne
2021-04-16 21:44 ` [dm-devel] " Mike Snitzer
2021-04-16 21:44 ` Mike Snitzer
2021-04-16 21:44 ` Mike Snitzer
2021-04-15 23:15 ` [dm-devel] [PATCH v2 4/4] nvme: decouple basic ANA log page re-read support from native multipathing Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
2021-04-15 23:15 ` Mike Snitzer
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=20210416150301.GC16047@redhat.com \
--to=snitzer@redhat.com \
--cc=axboe@kernel.dk \
--cc=dm-devel@redhat.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
/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.