linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] block: improvements for discard alignment
@ 2012-07-05 16:01 Paolo Bonzini
  2012-07-05 16:01 ` [PATCH v3 1/2] block: reorganize rounding of max_discard_sectors Paolo Bonzini
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Paolo Bonzini @ 2012-07-05 16:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: snitzer, david, dm-devel, xfs, hch, martin.petersen, axboe, vgoyal

When a disk has a large discard_granularity, discards are not split with
optimal alignment; the pessimization gets bigger as discard_granularity
and max_discard_sectors become closer.

Take the limit case of discard_granularity == max_discard_sectors == 64.
Then, if a request is submitted for 256 sectors 2..257 it will be split
like this: 2..65, 66..129, 130..193, 194..257.  None of these requests
is aligned, so in fact you might end up with no discarded logical blocks
at all.  With this patch, the split will be 2..63, 64..127, 128..191,
192..255, 256..257.  The patches also take the discard_alignment into
consideration.

Patch 1 adjusts the computation of the granularity-adjusted
max_discard_sectors so that it prepares for the new code in patch 2,
which actually adjusts the split.

v2->v3: drop addition of queue/discard_alignment to sysfs, use
  correct alignment for partitions

Paolo Bonzini (2):
  block: reorganize rounding of max_discard_sectors
  block: split discard into aligned requests

 block/blk-lib.c        |   41 ++++++++++++++++++++++++++++-------------
 include/linux/blkdev.h |   10 ++++++++++
 2 files changed, 38 insertions(+), 13 deletions(-)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/2] block: reorganize rounding of max_discard_sectors
  2012-07-05 16:01 [PATCH v3 0/2] block: improvements for discard alignment Paolo Bonzini
@ 2012-07-05 16:01 ` Paolo Bonzini
  2012-07-05 16:01 ` [PATCH v3 2/2] block: split discard into aligned requests Paolo Bonzini
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2012-07-05 16:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: snitzer, david, dm-devel, xfs, hch, martin.petersen, axboe, vgoyal

Mostly a preparation for the next patch.

In principle this fixes an infinite loop if max_discard_sectors < granularity,
but that really shouldn't happen.

Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/blk-lib.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index 2b461b4..16b06f6 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -44,6 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	struct request_queue *q = bdev_get_queue(bdev);
 	int type = REQ_WRITE | REQ_DISCARD;
 	unsigned int max_discard_sectors;
+	unsigned int granularity;
 	struct bio_batch bb;
 	struct bio *bio;
 	int ret = 0;
@@ -54,18 +55,18 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	if (!blk_queue_discard(q))
 		return -EOPNOTSUPP;
 
+	/* Zero-sector (unknown) and one-sector granularities are the same.  */
+	granularity = max(q->limits.discard_granularity >> 9, 1U);
+
 	/*
 	 * Ensure that max_discard_sectors is of the proper
 	 * granularity
 	 */
 	max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
+	max_discard_sectors = round_down(max_discard_sectors, granularity);
 	if (unlikely(!max_discard_sectors)) {
 		/* Avoid infinite loop below. Being cautious never hurts. */
 		return -EOPNOTSUPP;
-	} else if (q->limits.discard_granularity) {
-		unsigned int disc_sects = q->limits.discard_granularity >> 9;
-
-		max_discard_sectors &= ~(disc_sects - 1);
 	}
 
 	if (flags & BLKDEV_DISCARD_SECURE) {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/2] block: split discard into aligned requests
  2012-07-05 16:01 [PATCH v3 0/2] block: improvements for discard alignment Paolo Bonzini
  2012-07-05 16:01 ` [PATCH v3 1/2] block: reorganize rounding of max_discard_sectors Paolo Bonzini
@ 2012-07-05 16:01 ` Paolo Bonzini
  2012-07-17  7:20   ` Christoph Hellwig
  2012-07-05 21:43 ` [PATCH v3 0/2] block: improvements for discard alignment Vivek Goyal
  2012-08-01 13:40 ` Mike Snitzer
  3 siblings, 1 reply; 7+ messages in thread
From: Paolo Bonzini @ 2012-07-05 16:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: snitzer, david, dm-devel, xfs, hch, martin.petersen, axboe, vgoyal

When a disk has large discard_granularity and small max_discard_sectors,
discards are not split with optimal alignment.  In the limit case of
discard_granularity == max_discard_sectors, no request could be aligned
correctly, so in fact you might end up with no discarded logical blocks
at all.

Another example that helps showing the condition in the patch is with
discard_granularity == 64, max_discard_sectors == 128.  A request that is
submitted for 256 sectors 2..257 will be split in two: 2..129, 130..257.
However, only 2 aligned blocks out of 3 are included in the request;
128..191 may be left intact and not discarded.  With this patch, the
first request will be truncated to ensure good alignment of what's left,
and the split will be 2..127, 128..255, 256..257.  The patch will also
take into account the discard_alignment.

At most one extra request will be introduced, because the first request
will be reduced by at most granularity-1 sectors, and granularity
must be less than max_discard_sectors.  Subsequent requests will run
on round_down(max_discard_sectors, granularity) sectors, as in the
current code.

Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
        v2->v3: take into account partition alignment (Vivek)

 block/blk-lib.c        |   34 ++++++++++++++++++++++++----------
 include/linux/blkdev.h |   10 ++++++++++
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index 16b06f6..19cc761 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -44,7 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	struct request_queue *q = bdev_get_queue(bdev);
 	int type = REQ_WRITE | REQ_DISCARD;
 	unsigned int max_discard_sectors;
-	unsigned int granularity;
+	unsigned int granularity, alignment, mask;
 	struct bio_batch bb;
 	struct bio *bio;
 	int ret = 0;
@@ -57,10 +57,12 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 
 	/* Zero-sector (unknown) and one-sector granularities are the same.  */
 	granularity = max(q->limits.discard_granularity >> 9, 1U);
+	mask = granularity - 1;
+	alignment = (bdev_discard_alignment(bdev) >> 9) & mask;
 
 	/*
 	 * Ensure that max_discard_sectors is of the proper
-	 * granularity
+	 * granularity, so that requests stay aligned after a split.
 	 */
 	max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
 	max_discard_sectors = round_down(max_discard_sectors, granularity);
@@ -80,25 +82,37 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	bb.wait = &wait;
 
 	while (nr_sects) {
+		unsigned int req_sects;
+		sector_t end_sect;
+
 		bio = bio_alloc(gfp_mask, 1);
 		if (!bio) {
 			ret = -ENOMEM;
 			break;
 		}
 
+		req_sects = min_t(sector_t, nr_sects, max_discard_sectors);
+
+		/*
+		 * If splitting a request, and the next starting sector would be
+		 * misaligned, stop the discard at the previous aligned sector.
+		 */
+		end_sect = sector + req_sects;
+		if (req_sects < nr_sects && (end_sect & mask) != alignment) {
+			end_sect =
+				round_down(end_sect - alignment, granularity)
+				+ alignment;
+			req_sects = end_sect - sector;
+		}
+
 		bio->bi_sector = sector;
 		bio->bi_end_io = bio_batch_end_io;
 		bio->bi_bdev = bdev;
 		bio->bi_private = &bb;
 
-		if (nr_sects > max_discard_sectors) {
-			bio->bi_size = max_discard_sectors << 9;
-			nr_sects -= max_discard_sectors;
-			sector += max_discard_sectors;
-		} else {
-			bio->bi_size = nr_sects << 9;
-			nr_sects = 0;
-		}
+		bio->bi_size = req_sects << 9;
+		nr_sects -= req_sects;
+		sector = end_sect;
 
 		atomic_inc(&bb.done);
 		submit_bio(type, bio);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ba43f40..218de98 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1125,6 +1125,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
 		& (lim->discard_granularity - 1);
 }
 
+static inline int bdev_discard_alignment(struct block_device *bdev)
+{
+	struct request_queue *q = bdev_get_queue(bdev);
+
+	if (bdev != bdev->bd_contains)
+		return bdev->bd_part->discard_alignment;
+
+	return q->limits.discard_alignment;
+}
+
 static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
 {
 	if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] block: improvements for discard alignment
  2012-07-05 16:01 [PATCH v3 0/2] block: improvements for discard alignment Paolo Bonzini
  2012-07-05 16:01 ` [PATCH v3 1/2] block: reorganize rounding of max_discard_sectors Paolo Bonzini
  2012-07-05 16:01 ` [PATCH v3 2/2] block: split discard into aligned requests Paolo Bonzini
@ 2012-07-05 21:43 ` Vivek Goyal
  2012-08-01 13:40 ` Mike Snitzer
  3 siblings, 0 replies; 7+ messages in thread
From: Vivek Goyal @ 2012-07-05 21:43 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: linux-kernel, snitzer, david, dm-devel, xfs, hch, martin.petersen, axboe

On Thu, Jul 05, 2012 at 06:01:42PM +0200, Paolo Bonzini wrote:
> When a disk has a large discard_granularity, discards are not split with
> optimal alignment; the pessimization gets bigger as discard_granularity
> and max_discard_sectors become closer.
> 
> Take the limit case of discard_granularity == max_discard_sectors == 64.
> Then, if a request is submitted for 256 sectors 2..257 it will be split
> like this: 2..65, 66..129, 130..193, 194..257.  None of these requests
> is aligned, so in fact you might end up with no discarded logical blocks
> at all.  With this patch, the split will be 2..63, 64..127, 128..191,
> 192..255, 256..257.  The patches also take the discard_alignment into
> consideration.
> 
> Patch 1 adjusts the computation of the granularity-adjusted
> max_discard_sectors so that it prepares for the new code in patch 2,
> which actually adjusts the split.
> 
> v2->v3: drop addition of queue/discard_alignment to sysfs, use
>   correct alignment for partitions
> 
> Paolo Bonzini (2):
>   block: reorganize rounding of max_discard_sectors
>   block: split discard into aligned requests

Looks good to me. Did little testing with scsi_debug with discard_alignment=0
and discard_alignment=7 (sectors). We seem to be aligning requests better now.

Acked-by: Vivek Goyal <vgoyal@redhat.com>

Thanks
Vivek

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] block: split discard into aligned requests
  2012-07-05 16:01 ` [PATCH v3 2/2] block: split discard into aligned requests Paolo Bonzini
@ 2012-07-17  7:20   ` Christoph Hellwig
  0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2012-07-17  7:20 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: linux-kernel, axboe, snitzer, martin.petersen, xfs, dm-devel,
	hch, vgoyal

Looks good.

Any chance we can get this into the 3.6 queue (and possibly -stable)?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] block: improvements for discard alignment
  2012-07-05 16:01 [PATCH v3 0/2] block: improvements for discard alignment Paolo Bonzini
                   ` (2 preceding siblings ...)
  2012-07-05 21:43 ` [PATCH v3 0/2] block: improvements for discard alignment Vivek Goyal
@ 2012-08-01 13:40 ` Mike Snitzer
  2012-08-01 15:49   ` Jens Axboe
  3 siblings, 1 reply; 7+ messages in thread
From: Mike Snitzer @ 2012-08-01 13:40 UTC (permalink / raw)
  To: axboe
  Cc: linux-kernel, Paolo Bonzini, martin.petersen, david, xfs,
	dm-devel, hch, vgoyal

On Thu, Jul 05 2012 at 12:01pm -0400,
Paolo Bonzini <pbonzini@redhat.com> wrote:

> When a disk has a large discard_granularity, discards are not split with
> optimal alignment; the pessimization gets bigger as discard_granularity
> and max_discard_sectors become closer.
> 
> Take the limit case of discard_granularity == max_discard_sectors == 64.
> Then, if a request is submitted for 256 sectors 2..257 it will be split
> like this: 2..65, 66..129, 130..193, 194..257.  None of these requests
> is aligned, so in fact you might end up with no discarded logical blocks
> at all.  With this patch, the split will be 2..63, 64..127, 128..191,
> 192..255, 256..257.  The patches also take the discard_alignment into
> consideration.
> 
> Patch 1 adjusts the computation of the granularity-adjusted
> max_discard_sectors so that it prepares for the new code in patch 2,
> which actually adjusts the split.
> 
> v2->v3: drop addition of queue/discard_alignment to sysfs, use
>   correct alignment for partitions
> 
> Paolo Bonzini (2):
>   block: reorganize rounding of max_discard_sectors
>   block: split discard into aligned requests
> 
>  block/blk-lib.c        |   41 ++++++++++++++++++++++++++++-------------
>  include/linux/blkdev.h |   10 ++++++++++
>  2 files changed, 38 insertions(+), 13 deletions(-)

Hey Jens,

Would be great to get these discard fixes in.  I know both Christoph and
Vivek have reviewed these changes but that isn't reflected in the patch
headers.

These patches eliminate misaligned discard from being sent to the
dm-thinp target.

Tested-by: Mike Snitzer <snitzer@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] block: improvements for discard alignment
  2012-08-01 13:40 ` Mike Snitzer
@ 2012-08-01 15:49   ` Jens Axboe
  0 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2012-08-01 15:49 UTC (permalink / raw)
  To: Mike Snitzer
  Cc: linux-kernel, Paolo Bonzini, martin.petersen, david, xfs,
	dm-devel, hch, vgoyal

On 08/01/2012 03:40 PM, Mike Snitzer wrote:
> On Thu, Jul 05 2012 at 12:01pm -0400,
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> When a disk has a large discard_granularity, discards are not split with
>> optimal alignment; the pessimization gets bigger as discard_granularity
>> and max_discard_sectors become closer.
>>
>> Take the limit case of discard_granularity == max_discard_sectors == 64.
>> Then, if a request is submitted for 256 sectors 2..257 it will be split
>> like this: 2..65, 66..129, 130..193, 194..257.  None of these requests
>> is aligned, so in fact you might end up with no discarded logical blocks
>> at all.  With this patch, the split will be 2..63, 64..127, 128..191,
>> 192..255, 256..257.  The patches also take the discard_alignment into
>> consideration.
>>
>> Patch 1 adjusts the computation of the granularity-adjusted
>> max_discard_sectors so that it prepares for the new code in patch 2,
>> which actually adjusts the split.
>>
>> v2->v3: drop addition of queue/discard_alignment to sysfs, use
>>   correct alignment for partitions
>>
>> Paolo Bonzini (2):
>>   block: reorganize rounding of max_discard_sectors
>>   block: split discard into aligned requests
>>
>>  block/blk-lib.c        |   41 ++++++++++++++++++++++++++++-------------
>>  include/linux/blkdev.h |   10 ++++++++++
>>  2 files changed, 38 insertions(+), 13 deletions(-)
> 
> Hey Jens,
> 
> Would be great to get these discard fixes in.  I know both Christoph and
> Vivek have reviewed these changes but that isn't reflected in the patch
> headers.
> 
> These patches eliminate misaligned discard from being sent to the
> dm-thinp target.
> 
> Tested-by: Mike Snitzer <snitzer@redhat.com>

Sure, I'll get it in for this series. Thanks.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-08-01 15:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-05 16:01 [PATCH v3 0/2] block: improvements for discard alignment Paolo Bonzini
2012-07-05 16:01 ` [PATCH v3 1/2] block: reorganize rounding of max_discard_sectors Paolo Bonzini
2012-07-05 16:01 ` [PATCH v3 2/2] block: split discard into aligned requests Paolo Bonzini
2012-07-17  7:20   ` Christoph Hellwig
2012-07-05 21:43 ` [PATCH v3 0/2] block: improvements for discard alignment Vivek Goyal
2012-08-01 13:40 ` Mike Snitzer
2012-08-01 15:49   ` Jens Axboe

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).