* [PATCH] nvme: fix handling single range discard request
@ 2023-03-03 23:13 Ming Lei
2023-03-04 8:00 ` Hannes Reinecke
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Ming Lei @ 2023-03-03 23:13 UTC (permalink / raw)
To: Christoph Hellwig, Sagi Grimberg, linux-nvme; +Cc: linux-block, Ming Lei
When investigating one customer report on warning in nvme_setup_discard,
we observed the controller(nvme/tcp) actually exposes
queue_max_discard_segments(req->q) == 1.
Obviously the current code can't handle this situation, since contiguity
merge like normal RW request is taken.
Fix the issue by building range from request sector/nr_sectors directly.
Fixes: b35ba01ea697 ("nvme: support ranged discard requests")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
drivers/nvme/host/core.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c2730b116dc6..d4be525f8100 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
range = page_address(ns->ctrl->discard_page);
}
- __rq_for_each_bio(bio, req) {
- u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
- u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
-
- if (n < segments) {
- range[n].cattr = cpu_to_le32(0);
- range[n].nlb = cpu_to_le32(nlb);
- range[n].slba = cpu_to_le64(slba);
+ if (queue_max_discard_segments(req->q) == 1) {
+ u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req));
+ u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9);
+
+ range[0].cattr = cpu_to_le32(0);
+ range[0].nlb = cpu_to_le32(nlb);
+ range[0].slba = cpu_to_le64(slba);
+ n = 1;
+ } else {
+ __rq_for_each_bio(bio, req) {
+ u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
+ u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
+
+ if (n < segments) {
+ range[n].cattr = cpu_to_le32(0);
+ range[n].nlb = cpu_to_le32(nlb);
+ range[n].slba = cpu_to_le64(slba);
+ }
+ n++;
}
- n++;
}
if (WARN_ON_ONCE(n != segments)) {
--
2.39.2
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH] nvme: fix handling single range discard request 2023-03-03 23:13 [PATCH] nvme: fix handling single range discard request Ming Lei @ 2023-03-04 8:00 ` Hannes Reinecke 2023-03-04 10:22 ` Ming Lei 2023-03-06 14:21 ` Sagi Grimberg ` (2 subsequent siblings) 3 siblings, 1 reply; 15+ messages in thread From: Hannes Reinecke @ 2023-03-04 8:00 UTC (permalink / raw) To: Ming Lei, Christoph Hellwig, Sagi Grimberg, linux-nvme; +Cc: linux-block On 3/4/23 00:13, Ming Lei wrote: > When investigating one customer report on warning in nvme_setup_discard, > we observed the controller(nvme/tcp) actually exposes > queue_max_discard_segments(req->q) == 1. > > Obviously the current code can't handle this situation, since contiguity > merge like normal RW request is taken. > > Fix the issue by building range from request sector/nr_sectors directly. > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > Signed-off-by: Ming Lei <ming.lei@redhat.com> > --- > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > 1 file changed, 19 insertions(+), 9 deletions(-) > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > index c2730b116dc6..d4be525f8100 100644 > --- a/drivers/nvme/host/core.c > +++ b/drivers/nvme/host/core.c > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > range = page_address(ns->ctrl->discard_page); > } > > - __rq_for_each_bio(bio, req) { > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > - > - if (n < segments) { > - range[n].cattr = cpu_to_le32(0); > - range[n].nlb = cpu_to_le32(nlb); > - range[n].slba = cpu_to_le64(slba); > + if (queue_max_discard_segments(req->q) == 1) { > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > + > + range[0].cattr = cpu_to_le32(0); > + range[0].nlb = cpu_to_le32(nlb); > + range[0].slba = cpu_to_le64(slba); > + n = 1; > + } else { > + __rq_for_each_bio(bio, req) { > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > + > + if (n < segments) { > + range[n].cattr = cpu_to_le32(0); > + range[n].nlb = cpu_to_le32(nlb); > + range[n].slba = cpu_to_le64(slba); > + } > + n++; > } > - n++; > } > > if (WARN_ON_ONCE(n != segments)) { Now _that_ is odd. Looks like 'req' is not formatted according to the 'max_discard_sectors' setting. But if that's the case, then this 'fix' would fail whenever 'max_discard_sectors' < 'max_hw_sectors', right? Shouldn't we rather modify the merge algorithm to check for max_discard_sectors for DISCARD requests, such that we never _have_ mis-matched requests and this patch would be pointless? Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-04 8:00 ` Hannes Reinecke @ 2023-03-04 10:22 ` Ming Lei 2023-03-04 11:14 ` Hannes Reinecke 0 siblings, 1 reply; 15+ messages in thread From: Ming Lei @ 2023-03-04 10:22 UTC (permalink / raw) To: Hannes Reinecke Cc: Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-block, ming.lei On Sat, Mar 04, 2023 at 09:00:28AM +0100, Hannes Reinecke wrote: > On 3/4/23 00:13, Ming Lei wrote: > > When investigating one customer report on warning in nvme_setup_discard, > > we observed the controller(nvme/tcp) actually exposes > > queue_max_discard_segments(req->q) == 1. > > > > Obviously the current code can't handle this situation, since contiguity > > merge like normal RW request is taken. > > > > Fix the issue by building range from request sector/nr_sectors directly. > > > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > > Signed-off-by: Ming Lei <ming.lei@redhat.com> > > --- > > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > > 1 file changed, 19 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > index c2730b116dc6..d4be525f8100 100644 > > --- a/drivers/nvme/host/core.c > > +++ b/drivers/nvme/host/core.c > > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > > range = page_address(ns->ctrl->discard_page); > > } > > - __rq_for_each_bio(bio, req) { > > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > - > > - if (n < segments) { > > - range[n].cattr = cpu_to_le32(0); > > - range[n].nlb = cpu_to_le32(nlb); > > - range[n].slba = cpu_to_le64(slba); > > + if (queue_max_discard_segments(req->q) == 1) { > > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > > + > > + range[0].cattr = cpu_to_le32(0); > > + range[0].nlb = cpu_to_le32(nlb); > > + range[0].slba = cpu_to_le64(slba); > > + n = 1; > > + } else { > + __rq_for_each_bio(bio, req) { > > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > + > > + if (n < segments) { > > + range[n].cattr = cpu_to_le32(0); > > + range[n].nlb = cpu_to_le32(nlb); > > + range[n].slba = cpu_to_le64(slba); > > + } > > + n++; > > } > > - n++; > > } > > if (WARN_ON_ONCE(n != segments)) { > Now _that_ is odd. > Looks like 'req' is not formatted according to the 'max_discard_sectors' > setting. > But if that's the case, then this 'fix' would fail whenever > 'max_discard_sectors' < 'max_hw_sectors', right? No, it isn't the case. > Shouldn't we rather modify the merge algorithm to check for > max_discard_sectors for DISCARD requests, such that we never _have_ > mis-matched requests and this patch would be pointless? But it is related with discard merge. If queue_max_discard_segments() is 1, block layer merges discard request/bios just like normal RW IO. However, if queue_max_discard_segments() is > 1, block layer simply 'merges' all bios into one request, no matter if the LBA is adjacent or not, and treat each bio as one discard segment, that is called multi range discard too. That is the reason why we have to treat queue_max_discard_segments() == 1 specially, and you can see same handling in virtio_blk. Thanks, Ming ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-04 10:22 ` Ming Lei @ 2023-03-04 11:14 ` Hannes Reinecke 2023-03-04 12:02 ` Ming Lei 0 siblings, 1 reply; 15+ messages in thread From: Hannes Reinecke @ 2023-03-04 11:14 UTC (permalink / raw) To: Ming Lei; +Cc: Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-block On 3/4/23 11:22, Ming Lei wrote: > On Sat, Mar 04, 2023 at 09:00:28AM +0100, Hannes Reinecke wrote: >> On 3/4/23 00:13, Ming Lei wrote: >>> When investigating one customer report on warning in nvme_setup_discard, >>> we observed the controller(nvme/tcp) actually exposes >>> queue_max_discard_segments(req->q) == 1. >>> >>> Obviously the current code can't handle this situation, since contiguity >>> merge like normal RW request is taken. >>> >>> Fix the issue by building range from request sector/nr_sectors directly. >>> >>> Fixes: b35ba01ea697 ("nvme: support ranged discard requests") >>> Signed-off-by: Ming Lei <ming.lei@redhat.com> >>> --- >>> drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- >>> 1 file changed, 19 insertions(+), 9 deletions(-) >>> >>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >>> index c2730b116dc6..d4be525f8100 100644 >>> --- a/drivers/nvme/host/core.c >>> +++ b/drivers/nvme/host/core.c >>> @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, >>> range = page_address(ns->ctrl->discard_page); >>> } >>> - __rq_for_each_bio(bio, req) { >>> - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>> - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>> - >>> - if (n < segments) { >>> - range[n].cattr = cpu_to_le32(0); >>> - range[n].nlb = cpu_to_le32(nlb); >>> - range[n].slba = cpu_to_le64(slba); >>> + if (queue_max_discard_segments(req->q) == 1) { >>> + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); >>> + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); >>> + >>> + range[0].cattr = cpu_to_le32(0); >>> + range[0].nlb = cpu_to_le32(nlb); >>> + range[0].slba = cpu_to_le64(slba); >>> + n = 1; >>> + } else { > + __rq_for_each_bio(bio, req) { >>> + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>> + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>> + >>> + if (n < segments) { >>> + range[n].cattr = cpu_to_le32(0); >>> + range[n].nlb = cpu_to_le32(nlb); >>> + range[n].slba = cpu_to_le64(slba); >>> + } >>> + n++; >>> } >>> - n++; >>> } >>> if (WARN_ON_ONCE(n != segments)) { >> Now _that_ is odd. >> Looks like 'req' is not formatted according to the 'max_discard_sectors' >> setting. >> But if that's the case, then this 'fix' would fail whenever >> 'max_discard_sectors' < 'max_hw_sectors', right? > > No, it isn't the case. > >> Shouldn't we rather modify the merge algorithm to check for >> max_discard_sectors for DISCARD requests, such that we never _have_ >> mis-matched requests and this patch would be pointless? > > But it is related with discard merge. > > If queue_max_discard_segments() is 1, block layer merges discard > request/bios just like normal RW IO. > > However, if queue_max_discard_segments() is > 1, block layer simply > 'merges' all bios into one request, no matter if the LBA is adjacent > or not, and treat each bio as one discard segment, that is called > multi range discard too. > But wouldn't the number of bios be subject to 'queue_max_discard_segment', too? What guarantees we're not overflowing that for multi-segment discard merge? Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-04 11:14 ` Hannes Reinecke @ 2023-03-04 12:02 ` Ming Lei 0 siblings, 0 replies; 15+ messages in thread From: Ming Lei @ 2023-03-04 12:02 UTC (permalink / raw) To: Hannes Reinecke; +Cc: Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-block On Sat, Mar 04, 2023 at 12:14:30PM +0100, Hannes Reinecke wrote: > On 3/4/23 11:22, Ming Lei wrote: > > On Sat, Mar 04, 2023 at 09:00:28AM +0100, Hannes Reinecke wrote: > > > On 3/4/23 00:13, Ming Lei wrote: > > > > When investigating one customer report on warning in nvme_setup_discard, > > > > we observed the controller(nvme/tcp) actually exposes > > > > queue_max_discard_segments(req->q) == 1. > > > > > > > > Obviously the current code can't handle this situation, since contiguity > > > > merge like normal RW request is taken. > > > > > > > > Fix the issue by building range from request sector/nr_sectors directly. > > > > > > > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > > > > Signed-off-by: Ming Lei <ming.lei@redhat.com> > > > > --- > > > > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > > > > 1 file changed, 19 insertions(+), 9 deletions(-) > > > > > > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > > > index c2730b116dc6..d4be525f8100 100644 > > > > --- a/drivers/nvme/host/core.c > > > > +++ b/drivers/nvme/host/core.c > > > > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > > > > range = page_address(ns->ctrl->discard_page); > > > > } > > > > - __rq_for_each_bio(bio, req) { > > > > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > - > > > > - if (n < segments) { > > > > - range[n].cattr = cpu_to_le32(0); > > > > - range[n].nlb = cpu_to_le32(nlb); > > > > - range[n].slba = cpu_to_le64(slba); > > > > + if (queue_max_discard_segments(req->q) == 1) { > > > > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > > > > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > > > > + > > > > + range[0].cattr = cpu_to_le32(0); > > > > + range[0].nlb = cpu_to_le32(nlb); > > > > + range[0].slba = cpu_to_le64(slba); > > > > + n = 1; > > > > + } else { > + __rq_for_each_bio(bio, req) { > > > > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > + > > > > + if (n < segments) { > > > > + range[n].cattr = cpu_to_le32(0); > > > > + range[n].nlb = cpu_to_le32(nlb); > > > > + range[n].slba = cpu_to_le64(slba); > > > > + } > > > > + n++; > > > > } > > > > - n++; > > > > } > > > > if (WARN_ON_ONCE(n != segments)) { > > > Now _that_ is odd. > > > Looks like 'req' is not formatted according to the 'max_discard_sectors' > > > setting. > > > But if that's the case, then this 'fix' would fail whenever > > > 'max_discard_sectors' < 'max_hw_sectors', right? > > > > No, it isn't the case. > > > > > Shouldn't we rather modify the merge algorithm to check for > > > max_discard_sectors for DISCARD requests, such that we never _have_ > > > mis-matched requests and this patch would be pointless? > > > > But it is related with discard merge. > > > > If queue_max_discard_segments() is 1, block layer merges discard > > request/bios just like normal RW IO. > > > > However, if queue_max_discard_segments() is > 1, block layer simply > > 'merges' all bios into one request, no matter if the LBA is adjacent > > or not, and treat each bio as one discard segment, that is called > > multi range discard too. > > > But wouldn't the number of bios be subject to 'queue_max_discard_segment', > too? > What guarantees we're not overflowing that for multi-segment discard merge? block layer merge code makes sure that the max discard segment limit is respected, please see: req_attempt_discard_merge() bio_attempt_discard_merge() blk_recalc_rq_segments() Thanks, Ming ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-03 23:13 [PATCH] nvme: fix handling single range discard request Ming Lei 2023-03-04 8:00 ` Hannes Reinecke @ 2023-03-06 14:21 ` Sagi Grimberg 2023-03-06 21:49 ` Ming Lei 2023-03-08 5:38 ` Chaitanya Kulkarni 2023-03-09 9:41 ` Christoph Hellwig 3 siblings, 1 reply; 15+ messages in thread From: Sagi Grimberg @ 2023-03-06 14:21 UTC (permalink / raw) To: Ming Lei, Christoph Hellwig, linux-nvme; +Cc: linux-block On 3/4/23 01:13, Ming Lei wrote: > When investigating one customer report on warning in nvme_setup_discard, > we observed the controller(nvme/tcp) actually exposes > queue_max_discard_segments(req->q) == 1. > > Obviously the current code can't handle this situation, since contiguity > merge like normal RW request is taken. > > Fix the issue by building range from request sector/nr_sectors directly. > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > Signed-off-by: Ming Lei <ming.lei@redhat.com> > --- > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > 1 file changed, 19 insertions(+), 9 deletions(-) > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > index c2730b116dc6..d4be525f8100 100644 > --- a/drivers/nvme/host/core.c > +++ b/drivers/nvme/host/core.c > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > range = page_address(ns->ctrl->discard_page); > } > > - __rq_for_each_bio(bio, req) { > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > - > - if (n < segments) { > - range[n].cattr = cpu_to_le32(0); > - range[n].nlb = cpu_to_le32(nlb); > - range[n].slba = cpu_to_le64(slba); > + if (queue_max_discard_segments(req->q) == 1) { > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > + > + range[0].cattr = cpu_to_le32(0); > + range[0].nlb = cpu_to_le32(nlb); > + range[0].slba = cpu_to_le64(slba); > + n = 1; > + } else { > + __rq_for_each_bio(bio, req) { > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > + > + if (n < segments) { > + range[n].cattr = cpu_to_le32(0); > + range[n].nlb = cpu_to_le32(nlb); > + range[n].slba = cpu_to_le64(slba); > + } > + n++; > } > - n++; > } > > if (WARN_ON_ONCE(n != segments)) { Maybe just set segments to min(blk_rq_nr_discard_segments(req), queue_max_discard_segments(req->q)) and let the existing code do its thing? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-06 14:21 ` Sagi Grimberg @ 2023-03-06 21:49 ` Ming Lei 2023-03-07 11:39 ` Sagi Grimberg 0 siblings, 1 reply; 15+ messages in thread From: Ming Lei @ 2023-03-06 21:49 UTC (permalink / raw) To: Sagi Grimberg; +Cc: Christoph Hellwig, linux-nvme, linux-block, ming.lei On Mon, Mar 06, 2023 at 04:21:08PM +0200, Sagi Grimberg wrote: > > > On 3/4/23 01:13, Ming Lei wrote: > > When investigating one customer report on warning in nvme_setup_discard, > > we observed the controller(nvme/tcp) actually exposes > > queue_max_discard_segments(req->q) == 1. > > > > Obviously the current code can't handle this situation, since contiguity > > merge like normal RW request is taken. > > > > Fix the issue by building range from request sector/nr_sectors directly. > > > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > > Signed-off-by: Ming Lei <ming.lei@redhat.com> > > --- > > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > > 1 file changed, 19 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > index c2730b116dc6..d4be525f8100 100644 > > --- a/drivers/nvme/host/core.c > > +++ b/drivers/nvme/host/core.c > > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > > range = page_address(ns->ctrl->discard_page); > > } > > - __rq_for_each_bio(bio, req) { > > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > - > > - if (n < segments) { > > - range[n].cattr = cpu_to_le32(0); > > - range[n].nlb = cpu_to_le32(nlb); > > - range[n].slba = cpu_to_le64(slba); > > + if (queue_max_discard_segments(req->q) == 1) { > > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > > + > > + range[0].cattr = cpu_to_le32(0); > > + range[0].nlb = cpu_to_le32(nlb); > > + range[0].slba = cpu_to_le64(slba); > > + n = 1; > > + } else { > > + __rq_for_each_bio(bio, req) { > > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > + > > + if (n < segments) { > > + range[n].cattr = cpu_to_le32(0); > > + range[n].nlb = cpu_to_le32(nlb); > > + range[n].slba = cpu_to_le64(slba); > > + } > > + n++; > > } > > - n++; > > } > > if (WARN_ON_ONCE(n != segments)) { > > > Maybe just set segments to min(blk_rq_nr_discard_segments(req), > queue_max_discard_segments(req->q)) and let the existing code do > its thing? What is the existing code for applying min()? For block layer merge code, it has to cover two kinds of discard merge: - the traditional single range discard for most of devices - multi range discard merge for nvme and virtio-blk which takes same fix For driver side, it has to do similar handling if both single-range and multi-range discard are supported: - each bio is one discard range for multi-range discard - the whole request(may include more than 1 bios) is the single discard range for single-range discard Thanks, Ming ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-06 21:49 ` Ming Lei @ 2023-03-07 11:39 ` Sagi Grimberg 2023-03-07 12:14 ` Ming Lei 0 siblings, 1 reply; 15+ messages in thread From: Sagi Grimberg @ 2023-03-07 11:39 UTC (permalink / raw) To: Ming Lei; +Cc: Christoph Hellwig, linux-nvme, linux-block On 3/6/23 23:49, Ming Lei wrote: > On Mon, Mar 06, 2023 at 04:21:08PM +0200, Sagi Grimberg wrote: >> >> >> On 3/4/23 01:13, Ming Lei wrote: >>> When investigating one customer report on warning in nvme_setup_discard, >>> we observed the controller(nvme/tcp) actually exposes >>> queue_max_discard_segments(req->q) == 1. >>> >>> Obviously the current code can't handle this situation, since contiguity >>> merge like normal RW request is taken. >>> >>> Fix the issue by building range from request sector/nr_sectors directly. >>> >>> Fixes: b35ba01ea697 ("nvme: support ranged discard requests") >>> Signed-off-by: Ming Lei <ming.lei@redhat.com> >>> --- >>> drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- >>> 1 file changed, 19 insertions(+), 9 deletions(-) >>> >>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >>> index c2730b116dc6..d4be525f8100 100644 >>> --- a/drivers/nvme/host/core.c >>> +++ b/drivers/nvme/host/core.c >>> @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, >>> range = page_address(ns->ctrl->discard_page); >>> } >>> - __rq_for_each_bio(bio, req) { >>> - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>> - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>> - >>> - if (n < segments) { >>> - range[n].cattr = cpu_to_le32(0); >>> - range[n].nlb = cpu_to_le32(nlb); >>> - range[n].slba = cpu_to_le64(slba); >>> + if (queue_max_discard_segments(req->q) == 1) { >>> + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); >>> + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); >>> + >>> + range[0].cattr = cpu_to_le32(0); >>> + range[0].nlb = cpu_to_le32(nlb); >>> + range[0].slba = cpu_to_le64(slba); >>> + n = 1; >>> + } else { >>> + __rq_for_each_bio(bio, req) { >>> + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>> + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>> + >>> + if (n < segments) { >>> + range[n].cattr = cpu_to_le32(0); >>> + range[n].nlb = cpu_to_le32(nlb); >>> + range[n].slba = cpu_to_le64(slba); >>> + } >>> + n++; >>> } >>> - n++; >>> } >>> if (WARN_ON_ONCE(n != segments)) { >> >> >> Maybe just set segments to min(blk_rq_nr_discard_segments(req), >> queue_max_discard_segments(req->q)) and let the existing code do >> its thing? > > What is the existing code for applying min()? Was referring to this: -- diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 3345f866178e..dbc402587431 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, range = page_address(ns->ctrl->discard_page); } + segments = min(segments, queue_max_discard_segments(req->q)); __rq_for_each_bio(bio, req) { u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; -- ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-07 11:39 ` Sagi Grimberg @ 2023-03-07 12:14 ` Ming Lei 2023-03-07 12:31 ` Sagi Grimberg 0 siblings, 1 reply; 15+ messages in thread From: Ming Lei @ 2023-03-07 12:14 UTC (permalink / raw) To: Sagi Grimberg; +Cc: Christoph Hellwig, linux-nvme, linux-block, ming.lei On Tue, Mar 07, 2023 at 01:39:27PM +0200, Sagi Grimberg wrote: > > > On 3/6/23 23:49, Ming Lei wrote: > > On Mon, Mar 06, 2023 at 04:21:08PM +0200, Sagi Grimberg wrote: > > > > > > > > > On 3/4/23 01:13, Ming Lei wrote: > > > > When investigating one customer report on warning in nvme_setup_discard, > > > > we observed the controller(nvme/tcp) actually exposes > > > > queue_max_discard_segments(req->q) == 1. > > > > > > > > Obviously the current code can't handle this situation, since contiguity > > > > merge like normal RW request is taken. > > > > > > > > Fix the issue by building range from request sector/nr_sectors directly. > > > > > > > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > > > > Signed-off-by: Ming Lei <ming.lei@redhat.com> > > > > --- > > > > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > > > > 1 file changed, 19 insertions(+), 9 deletions(-) > > > > > > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > > > index c2730b116dc6..d4be525f8100 100644 > > > > --- a/drivers/nvme/host/core.c > > > > +++ b/drivers/nvme/host/core.c > > > > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > > > > range = page_address(ns->ctrl->discard_page); > > > > } > > > > - __rq_for_each_bio(bio, req) { > > > > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > - > > > > - if (n < segments) { > > > > - range[n].cattr = cpu_to_le32(0); > > > > - range[n].nlb = cpu_to_le32(nlb); > > > > - range[n].slba = cpu_to_le64(slba); > > > > + if (queue_max_discard_segments(req->q) == 1) { > > > > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > > > > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > > > > + > > > > + range[0].cattr = cpu_to_le32(0); > > > > + range[0].nlb = cpu_to_le32(nlb); > > > > + range[0].slba = cpu_to_le64(slba); > > > > + n = 1; > > > > + } else { > > > > + __rq_for_each_bio(bio, req) { > > > > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > + > > > > + if (n < segments) { > > > > + range[n].cattr = cpu_to_le32(0); > > > > + range[n].nlb = cpu_to_le32(nlb); > > > > + range[n].slba = cpu_to_le64(slba); > > > > + } > > > > + n++; > > > > } > > > > - n++; > > > > } > > > > if (WARN_ON_ONCE(n != segments)) { > > > > > > > > > Maybe just set segments to min(blk_rq_nr_discard_segments(req), > > > queue_max_discard_segments(req->q)) and let the existing code do > > > its thing? > > > > What is the existing code for applying min()? > > Was referring to this: > -- > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > index 3345f866178e..dbc402587431 100644 > --- a/drivers/nvme/host/core.c > +++ b/drivers/nvme/host/core.c > @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns > *ns, struct request *req, > range = page_address(ns->ctrl->discard_page); > } > > + segments = min(segments, queue_max_discard_segments(req->q)); That can't work. In case of queue_max_discard_segments(req->q) == 1, the request still can have more than one bios since the normal merge is taken for discard IOs. Thanks, Ming ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-07 12:14 ` Ming Lei @ 2023-03-07 12:31 ` Sagi Grimberg 2023-03-07 14:24 ` Ming Lei 2023-03-08 5:36 ` Chaitanya Kulkarni 0 siblings, 2 replies; 15+ messages in thread From: Sagi Grimberg @ 2023-03-07 12:31 UTC (permalink / raw) To: Ming Lei; +Cc: Christoph Hellwig, linux-nvme, linux-block On 3/7/23 14:14, Ming Lei wrote: > On Tue, Mar 07, 2023 at 01:39:27PM +0200, Sagi Grimberg wrote: >> >> >> On 3/6/23 23:49, Ming Lei wrote: >>> On Mon, Mar 06, 2023 at 04:21:08PM +0200, Sagi Grimberg wrote: >>>> >>>> >>>> On 3/4/23 01:13, Ming Lei wrote: >>>>> When investigating one customer report on warning in nvme_setup_discard, >>>>> we observed the controller(nvme/tcp) actually exposes >>>>> queue_max_discard_segments(req->q) == 1. >>>>> >>>>> Obviously the current code can't handle this situation, since contiguity >>>>> merge like normal RW request is taken. >>>>> >>>>> Fix the issue by building range from request sector/nr_sectors directly. >>>>> >>>>> Fixes: b35ba01ea697 ("nvme: support ranged discard requests") >>>>> Signed-off-by: Ming Lei <ming.lei@redhat.com> >>>>> --- >>>>> drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- >>>>> 1 file changed, 19 insertions(+), 9 deletions(-) >>>>> >>>>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >>>>> index c2730b116dc6..d4be525f8100 100644 >>>>> --- a/drivers/nvme/host/core.c >>>>> +++ b/drivers/nvme/host/core.c >>>>> @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, >>>>> range = page_address(ns->ctrl->discard_page); >>>>> } >>>>> - __rq_for_each_bio(bio, req) { >>>>> - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>>>> - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>>>> - >>>>> - if (n < segments) { >>>>> - range[n].cattr = cpu_to_le32(0); >>>>> - range[n].nlb = cpu_to_le32(nlb); >>>>> - range[n].slba = cpu_to_le64(slba); >>>>> + if (queue_max_discard_segments(req->q) == 1) { >>>>> + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); >>>>> + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); >>>>> + >>>>> + range[0].cattr = cpu_to_le32(0); >>>>> + range[0].nlb = cpu_to_le32(nlb); >>>>> + range[0].slba = cpu_to_le64(slba); >>>>> + n = 1; >>>>> + } else { >>>>> + __rq_for_each_bio(bio, req) { >>>>> + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); >>>>> + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; >>>>> + >>>>> + if (n < segments) { >>>>> + range[n].cattr = cpu_to_le32(0); >>>>> + range[n].nlb = cpu_to_le32(nlb); >>>>> + range[n].slba = cpu_to_le64(slba); >>>>> + } >>>>> + n++; >>>>> } >>>>> - n++; >>>>> } >>>>> if (WARN_ON_ONCE(n != segments)) { >>>> >>>> >>>> Maybe just set segments to min(blk_rq_nr_discard_segments(req), >>>> queue_max_discard_segments(req->q)) and let the existing code do >>>> its thing? >>> >>> What is the existing code for applying min()? >> >> Was referring to this: >> -- >> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >> index 3345f866178e..dbc402587431 100644 >> --- a/drivers/nvme/host/core.c >> +++ b/drivers/nvme/host/core.c >> @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns >> *ns, struct request *req, >> range = page_address(ns->ctrl->discard_page); >> } >> >> + segments = min(segments, queue_max_discard_segments(req->q)); > > That can't work. > > In case of queue_max_discard_segments(req->q) == 1, the request still > can have more than one bios since the normal merge is taken for discard > IOs. Ah, I see, the bios are contiguous though right? We could add a contiguity check in the loop and conditionally increment n, but maybe that would probably be more complicated... ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-07 12:31 ` Sagi Grimberg @ 2023-03-07 14:24 ` Ming Lei 2023-03-08 5:42 ` Chaitanya Kulkarni 2023-03-08 5:36 ` Chaitanya Kulkarni 1 sibling, 1 reply; 15+ messages in thread From: Ming Lei @ 2023-03-07 14:24 UTC (permalink / raw) To: Sagi Grimberg; +Cc: Christoph Hellwig, linux-nvme, linux-block On Tue, Mar 07, 2023 at 02:31:48PM +0200, Sagi Grimberg wrote: > > > On 3/7/23 14:14, Ming Lei wrote: > > On Tue, Mar 07, 2023 at 01:39:27PM +0200, Sagi Grimberg wrote: > > > > > > > > > On 3/6/23 23:49, Ming Lei wrote: > > > > On Mon, Mar 06, 2023 at 04:21:08PM +0200, Sagi Grimberg wrote: > > > > > > > > > > > > > > > On 3/4/23 01:13, Ming Lei wrote: > > > > > > When investigating one customer report on warning in nvme_setup_discard, > > > > > > we observed the controller(nvme/tcp) actually exposes > > > > > > queue_max_discard_segments(req->q) == 1. > > > > > > > > > > > > Obviously the current code can't handle this situation, since contiguity > > > > > > merge like normal RW request is taken. > > > > > > > > > > > > Fix the issue by building range from request sector/nr_sectors directly. > > > > > > > > > > > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > > > > > > Signed-off-by: Ming Lei <ming.lei@redhat.com> > > > > > > --- > > > > > > drivers/nvme/host/core.c | 28 +++++++++++++++++++--------- > > > > > > 1 file changed, 19 insertions(+), 9 deletions(-) > > > > > > > > > > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > > > > > index c2730b116dc6..d4be525f8100 100644 > > > > > > --- a/drivers/nvme/host/core.c > > > > > > +++ b/drivers/nvme/host/core.c > > > > > > @@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, > > > > > > range = page_address(ns->ctrl->discard_page); > > > > > > } > > > > > > - __rq_for_each_bio(bio, req) { > > > > > > - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > > > - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > > > - > > > > > > - if (n < segments) { > > > > > > - range[n].cattr = cpu_to_le32(0); > > > > > > - range[n].nlb = cpu_to_le32(nlb); > > > > > > - range[n].slba = cpu_to_le64(slba); > > > > > > + if (queue_max_discard_segments(req->q) == 1) { > > > > > > + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); > > > > > > + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); > > > > > > + > > > > > > + range[0].cattr = cpu_to_le32(0); > > > > > > + range[0].nlb = cpu_to_le32(nlb); > > > > > > + range[0].slba = cpu_to_le64(slba); > > > > > > + n = 1; > > > > > > + } else { > > > > > > + __rq_for_each_bio(bio, req) { > > > > > > + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); > > > > > > + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; > > > > > > + > > > > > > + if (n < segments) { > > > > > > + range[n].cattr = cpu_to_le32(0); > > > > > > + range[n].nlb = cpu_to_le32(nlb); > > > > > > + range[n].slba = cpu_to_le64(slba); > > > > > > + } > > > > > > + n++; > > > > > > } > > > > > > - n++; > > > > > > } > > > > > > if (WARN_ON_ONCE(n != segments)) { > > > > > > > > > > > > > > > Maybe just set segments to min(blk_rq_nr_discard_segments(req), > > > > > queue_max_discard_segments(req->q)) and let the existing code do > > > > > its thing? > > > > > > > > What is the existing code for applying min()? > > > > > > Was referring to this: > > > -- > > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > > > index 3345f866178e..dbc402587431 100644 > > > --- a/drivers/nvme/host/core.c > > > +++ b/drivers/nvme/host/core.c > > > @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns > > > *ns, struct request *req, > > > range = page_address(ns->ctrl->discard_page); > > > } > > > > > > + segments = min(segments, queue_max_discard_segments(req->q)); > > > > That can't work. > > > > In case of queue_max_discard_segments(req->q) == 1, the request still > > can have more than one bios since the normal merge is taken for discard > > IOs. > > Ah, I see, the bios are contiguous though right? Yes, the merge is just like normal RW. > We could add a contiguity check in the loop and conditionally > increment n, but maybe that would probably be more complicated... That is more complicated than this patch, and the same pattern has been applied on virtio-blk. Thanks, Ming ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-07 14:24 ` Ming Lei @ 2023-03-08 5:42 ` Chaitanya Kulkarni 0 siblings, 0 replies; 15+ messages in thread From: Chaitanya Kulkarni @ 2023-03-08 5:42 UTC (permalink / raw) To: Ming Lei, Sagi Grimberg Cc: Christoph Hellwig, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org >>>> Was referring to this: >>>> -- >>>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >>>> index 3345f866178e..dbc402587431 100644 >>>> --- a/drivers/nvme/host/core.c >>>> +++ b/drivers/nvme/host/core.c >>>> @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct nvme_ns >>>> *ns, struct request *req, >>>> range = page_address(ns->ctrl->discard_page); >>>> } >>>> >>>> + segments = min(segments, queue_max_discard_segments(req->q)); >>> >>> That can't work. >>> >>> In case of queue_max_discard_segments(req->q) == 1, the request still >>> can have more than one bios since the normal merge is taken for discard >>> IOs. >> >> Ah, I see, the bios are contiguous though right? > > Yes, the merge is just like normal RW. > >> We could add a contiguity check in the loop and conditionally >> increment n, but maybe that would probably be more complicated... > > That is more complicated than this patch, and the same pattern > has been applied on virtio-blk. > I'd very much keep the pattern in virio-blk in nvme that is easier to read and simple than conditional increment of the n, unless there is a strong reason for not doing that, which I failed to understand ... -ck ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-07 12:31 ` Sagi Grimberg 2023-03-07 14:24 ` Ming Lei @ 2023-03-08 5:36 ` Chaitanya Kulkarni 1 sibling, 0 replies; 15+ messages in thread From: Chaitanya Kulkarni @ 2023-03-08 5:36 UTC (permalink / raw) To: Sagi Grimberg, Ming Lei Cc: Christoph Hellwig, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org >>> Was referring to this: >>> -- >>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c >>> index 3345f866178e..dbc402587431 100644 >>> --- a/drivers/nvme/host/core.c >>> +++ b/drivers/nvme/host/core.c >>> @@ -781,6 +781,7 @@ static blk_status_t nvme_setup_discard(struct >>> nvme_ns >>> *ns, struct request *req, >>> range = page_address(ns->ctrl->discard_page); >>> } >>> >>> + segments = min(segments, queue_max_discard_segments(req->q)); >> >> That can't work. >> >> In case of queue_max_discard_segments(req->q) == 1, the request still >> can have more than one bios since the normal merge is taken for discard >> IOs. > > Ah, I see, the bios are contiguous though right? > We could add a contiguity check in the loop and conditionally > increment n, but maybe that would probably be more complicated... It will be great if we can avoid above mentioned complicated pattern... -ck ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-03 23:13 [PATCH] nvme: fix handling single range discard request Ming Lei 2023-03-04 8:00 ` Hannes Reinecke 2023-03-06 14:21 ` Sagi Grimberg @ 2023-03-08 5:38 ` Chaitanya Kulkarni 2023-03-09 9:41 ` Christoph Hellwig 3 siblings, 0 replies; 15+ messages in thread From: Chaitanya Kulkarni @ 2023-03-08 5:38 UTC (permalink / raw) To: Ming Lei Cc: linux-block@vger.kernel.org, linux-nvme@lists.infradead.org, Sagi Grimberg, Christoph Hellwig On 3/3/2023 3:13 PM, Ming Lei wrote: > When investigating one customer report on warning in nvme_setup_discard, > we observed the controller(nvme/tcp) actually exposes > queue_max_discard_segments(req->q) == 1. > > Obviously the current code can't handle this situation, since contiguity > merge like normal RW request is taken. > > Fix the issue by building range from request sector/nr_sectors directly. > > Fixes: b35ba01ea697 ("nvme: support ranged discard requests") > Signed-off-by: Ming Lei <ming.lei@redhat.com> > --- Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> -ck ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] nvme: fix handling single range discard request 2023-03-03 23:13 [PATCH] nvme: fix handling single range discard request Ming Lei ` (2 preceding siblings ...) 2023-03-08 5:38 ` Chaitanya Kulkarni @ 2023-03-09 9:41 ` Christoph Hellwig 3 siblings, 0 replies; 15+ messages in thread From: Christoph Hellwig @ 2023-03-09 9:41 UTC (permalink / raw) To: Ming Lei; +Cc: Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-block Thanks, applied to nvme-6.3. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2023-03-09 9:42 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-03-03 23:13 [PATCH] nvme: fix handling single range discard request Ming Lei 2023-03-04 8:00 ` Hannes Reinecke 2023-03-04 10:22 ` Ming Lei 2023-03-04 11:14 ` Hannes Reinecke 2023-03-04 12:02 ` Ming Lei 2023-03-06 14:21 ` Sagi Grimberg 2023-03-06 21:49 ` Ming Lei 2023-03-07 11:39 ` Sagi Grimberg 2023-03-07 12:14 ` Ming Lei 2023-03-07 12:31 ` Sagi Grimberg 2023-03-07 14:24 ` Ming Lei 2023-03-08 5:42 ` Chaitanya Kulkarni 2023-03-08 5:36 ` Chaitanya Kulkarni 2023-03-08 5:38 ` Chaitanya Kulkarni 2023-03-09 9:41 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox