stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop
@ 2020-08-17 10:01 Ming Lei
  2020-08-17 10:17 ` Christoph Hellwig
  2020-08-17 13:58 ` Jens Axboe
  0 siblings, 2 replies; 4+ messages in thread
From: Ming Lei @ 2020-08-17 10:01 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Ming Lei, Coly Li, Hannes Reinecke, Xiao Ni,
	Martin K . Petersen, Evan Green, Gwendal Grignou,
	Chaitanya Kulkarni, Andrzej Pietrasiewicz, Christoph Hellwig,
	stable

In case of block device backend, if the backend supports write zeros, the
loop device will set queue flag of QUEUE_FLAG_DISCARD. However,
limits.discard_granularity isn't setup, and this way is wrong,
see the following description in Documentation/ABI/testing/sysfs-block:

	A discard_granularity of 0 means that the device does not support
	discard functionality.

Especially 9b15d109a6b2 ("block: improve discard bio alignment in
__blkdev_issue_discard()") starts to take q->limits.discard_granularity
for computing max discard sectors. And zero discard granularity may cause
kernel oops, or fail discard request even though the loop queue claims
discard support via QUEUE_FLAG_DISCARD.

Fix the issue by setup discard granularity and alignment.

Fixes: c52abf563049 ("loop: Better discard support for block devices")
Acked-by: Coly Li <colyli@suse.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Xiao Ni <xni@redhat.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Evan Green <evgreen@chromium.org>
Cc: Gwendal Grignou <gwendal@chromium.org>
Cc: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/block/loop.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2f137d6ce169..3d7a1901bf28 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -878,6 +878,7 @@ static void loop_config_discard(struct loop_device *lo)
 	struct file *file = lo->lo_backing_file;
 	struct inode *inode = file->f_mapping->host;
 	struct request_queue *q = lo->lo_queue;
+	u32 granularity, max_discard_sectors;
 
 	/*
 	 * If the backing device is a block device, mirror its zeroing
@@ -890,11 +891,10 @@ static void loop_config_discard(struct loop_device *lo)
 		struct request_queue *backingq;
 
 		backingq = bdev_get_queue(inode->i_bdev);
-		blk_queue_max_discard_sectors(q,
-			backingq->limits.max_write_zeroes_sectors);
 
-		blk_queue_max_write_zeroes_sectors(q,
-			backingq->limits.max_write_zeroes_sectors);
+		max_discard_sectors = backingq->limits.max_write_zeroes_sectors;
+		granularity = backingq->limits.discard_granularity ?:
+			queue_physical_block_size(backingq);
 
 	/*
 	 * We use punch hole to reclaim the free space used by the
@@ -903,23 +903,26 @@ static void loop_config_discard(struct loop_device *lo)
 	 * useful information.
 	 */
 	} else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) {
-		q->limits.discard_granularity = 0;
-		q->limits.discard_alignment = 0;
-		blk_queue_max_discard_sectors(q, 0);
-		blk_queue_max_write_zeroes_sectors(q, 0);
+		max_discard_sectors = 0;
+		granularity = 0;
 
 	} else {
-		q->limits.discard_granularity = inode->i_sb->s_blocksize;
-		q->limits.discard_alignment = 0;
-
-		blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
-		blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
+		max_discard_sectors = UINT_MAX >> 9;
+		granularity = inode->i_sb->s_blocksize;
 	}
 
-	if (q->limits.max_write_zeroes_sectors)
+	if (max_discard_sectors) {
+		q->limits.discard_granularity = granularity;
+		blk_queue_max_discard_sectors(q, max_discard_sectors);
+		blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
 		blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
-	else
+	} else {
+		q->limits.discard_granularity = 0;
+		blk_queue_max_discard_sectors(q, 0);
+		blk_queue_max_write_zeroes_sectors(q, 0);
 		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
+	}
+	q->limits.discard_alignment = 0;
 }
 
 static void loop_unprepare_queue(struct loop_device *lo)
-- 
2.25.2


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

* Re: [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop
  2020-08-17 10:01 [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop Ming Lei
@ 2020-08-17 10:17 ` Christoph Hellwig
  2020-08-18  3:00   ` Martin K. Petersen
  2020-08-17 13:58 ` Jens Axboe
  1 sibling, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2020-08-17 10:17 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, linux-block, Coly Li, Hannes Reinecke, Xiao Ni,
	Martin K . Petersen, Evan Green, Gwendal Grignou,
	Chaitanya Kulkarni, Andrzej Pietrasiewicz, Christoph Hellwig,
	stable

On Mon, Aug 17, 2020 at 06:01:30PM +0800, Ming Lei wrote:
> In case of block device backend, if the backend supports write zeros, the
> loop device will set queue flag of QUEUE_FLAG_DISCARD. However,
> limits.discard_granularity isn't setup, and this way is wrong,
> see the following description in Documentation/ABI/testing/sysfs-block:
> 
> 	A discard_granularity of 0 means that the device does not support
> 	discard functionality.
> 
> Especially 9b15d109a6b2 ("block: improve discard bio alignment in
> __blkdev_issue_discard()") starts to take q->limits.discard_granularity
> for computing max discard sectors. And zero discard granularity may cause
> kernel oops, or fail discard request even though the loop queue claims
> discard support via QUEUE_FLAG_DISCARD.
> 
> Fix the issue by setup discard granularity and alignment.

This patch looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

If you have a few spare cycles, can you kill QUEUE_FLAG_DISCARD and
just key off discard support based on checking discard_granularity to
avoid problems like this in the future?

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

* Re: [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop
  2020-08-17 10:01 [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop Ming Lei
  2020-08-17 10:17 ` Christoph Hellwig
@ 2020-08-17 13:58 ` Jens Axboe
  1 sibling, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2020-08-17 13:58 UTC (permalink / raw)
  To: Ming Lei
  Cc: linux-block, Coly Li, Hannes Reinecke, Xiao Ni,
	Martin K . Petersen, Evan Green, Gwendal Grignou,
	Chaitanya Kulkarni, Andrzej Pietrasiewicz, Christoph Hellwig,
	stable

On 8/17/20 3:01 AM, Ming Lei wrote:
> In case of block device backend, if the backend supports write zeros, the
> loop device will set queue flag of QUEUE_FLAG_DISCARD. However,
> limits.discard_granularity isn't setup, and this way is wrong,
> see the following description in Documentation/ABI/testing/sysfs-block:
> 
> 	A discard_granularity of 0 means that the device does not support
> 	discard functionality.
> 
> Especially 9b15d109a6b2 ("block: improve discard bio alignment in
> __blkdev_issue_discard()") starts to take q->limits.discard_granularity
> for computing max discard sectors. And zero discard granularity may cause
> kernel oops, or fail discard request even though the loop queue claims
> discard support via QUEUE_FLAG_DISCARD.
> 
> Fix the issue by setup discard granularity and alignment.

Applied, thanks.

-- 
Jens Axboe


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

* Re: [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop
  2020-08-17 10:17 ` Christoph Hellwig
@ 2020-08-18  3:00   ` Martin K. Petersen
  0 siblings, 0 replies; 4+ messages in thread
From: Martin K. Petersen @ 2020-08-18  3:00 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Ming Lei, Jens Axboe, linux-block, Coly Li, Hannes Reinecke,
	Xiao Ni, Martin K . Petersen, Evan Green, Gwendal Grignou,
	Chaitanya Kulkarni, Andrzej Pietrasiewicz, stable


Christoph,

> If you have a few spare cycles, can you kill QUEUE_FLAG_DISCARD and
> just key off discard support based on checking discard_granularity to
> avoid problems like this in the future?

Yes, that would be great!

-- 
Martin K. Petersen	Oracle Linux Engineering

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

end of thread, other threads:[~2020-08-18  3:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-17 10:01 [PATCH RESEND] block: loop: set discard granularity and alignment for block device backed loop Ming Lei
2020-08-17 10:17 ` Christoph Hellwig
2020-08-18  3:00   ` Martin K. Petersen
2020-08-17 13:58 ` 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).