Message ID | 73c46137-c06e-348f-3d37-8c305ad4c4f3@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | brd discard patches | expand |
On 7/19/2023 1:21 PM, Mikulas Patocka wrote: > This patch implements REQ_OP_WRITE_ZEROES on brd. Write zeroes will free > the pages just like discard, but the difference is that it writes zeroes > to the preceding and following page if the range is not aligned on page > boundary. > > Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> > > --- > drivers/block/brd.c | 22 ++++++++++++++++++---- > 1 file changed, 18 insertions(+), 4 deletions(-) > > Index: linux-2.6/drivers/block/brd.c > =================================================================== > --- linux-2.6.orig/drivers/block/brd.c > +++ linux-2.6/drivers/block/brd.c > @@ -272,7 +272,8 @@ out: > > void brd_do_discard(struct brd_device *brd, struct bio *bio) > { > - sector_t sector, len, front_pad; > + bool zero_padding = bio_op(bio) == REQ_OP_WRITE_ZEROES; > + sector_t sector, len, front_pad, end_pad; > > if (unlikely(!discard)) { > bio->bi_status = BLK_STS_NOTSUPP; > @@ -282,11 +283,22 @@ void brd_do_discard(struct brd_device *b > sector = bio->bi_iter.bi_sector; > len = bio_sectors(bio); > front_pad = -sector & (PAGE_SECTORS - 1); > + > + if (zero_padding && unlikely(front_pad != 0)) > + copy_to_brd(brd, page_address(ZERO_PAGE(0)), > + sector, min(len, front_pad) << SECTOR_SHIFT); > + Is it possible to create different interface for discard and write zeroes ? I think it is a lot of logic adding on one function if everyone else is okay please discard my comment .. > sector += front_pad; > if (unlikely(len <= front_pad)) > return; > len -= front_pad; > - len = round_down(len, PAGE_SECTORS); > + > + end_pad = len & (PAGE_SECTORS - 1); > + if (zero_padding && unlikely(end_pad != 0)) > + copy_to_brd(brd, page_address(ZERO_PAGE(0)), > + sector + len - end_pad, end_pad << SECTOR_SHIFT); > + len -= end_pad; > + > while (len) { > brd_free_page(brd, sector); > sector += PAGE_SECTORS; > @@ -302,7 +314,8 @@ static void brd_submit_bio(struct bio *b > struct bio_vec bvec; > struct bvec_iter iter; > > - if (bio_op(bio) == REQ_OP_DISCARD) { > + if (bio_op(bio) == REQ_OP_DISCARD || > + bio_op(bio) == REQ_OP_WRITE_ZEROES) { > brd_do_discard(brd, bio); > goto endio; > } can we please use switch ? unless there is a strong need for if which I failed to understand ... > @@ -355,7 +368,7 @@ MODULE_PARM_DESC(max_part, "Num Minors t > > static bool discard = false; > module_param(discard, bool, 0444); > -MODULE_PARM_DESC(discard, "Support discard"); > +MODULE_PARM_DESC(discard, "Support discard and write zeroes"); > write-zeroes and discards are both different req_op and they should have a separate module parameter ... > MODULE_LICENSE("GPL"); > MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); > @@ -425,6 +438,7 @@ static int brd_alloc(int i) > if (discard) { > disk->queue->limits.discard_granularity = PAGE_SIZE; > blk_queue_max_discard_sectors(disk->queue, round_down(UINT_MAX, PAGE_SECTORS)); > + blk_queue_max_write_zeroes_sectors(disk->queue, round_down(UINT_MAX, PAGE_SECTORS)); above should be moved to new module parameter write_zeroes, unless there is a reason to use one module parameter for both req_op... > } > > /* Tell the block layer that this is not a rotational device */ > -ck
On Thu, 20 Jul 2023, Chaitanya Kulkarni wrote: > > Index: linux-2.6/drivers/block/brd.c > > =================================================================== > > --- linux-2.6.orig/drivers/block/brd.c > > +++ linux-2.6/drivers/block/brd.c > > @@ -272,7 +272,8 @@ out: > > > > void brd_do_discard(struct brd_device *brd, struct bio *bio) > > { > > - sector_t sector, len, front_pad; > > + bool zero_padding = bio_op(bio) == REQ_OP_WRITE_ZEROES; > > + sector_t sector, len, front_pad, end_pad; > > > > if (unlikely(!discard)) { > > bio->bi_status = BLK_STS_NOTSUPP; > > @@ -282,11 +283,22 @@ void brd_do_discard(struct brd_device *b > > sector = bio->bi_iter.bi_sector; > > len = bio_sectors(bio); > > front_pad = -sector & (PAGE_SECTORS - 1); > > + > > + if (zero_padding && unlikely(front_pad != 0)) > > + copy_to_brd(brd, page_address(ZERO_PAGE(0)), > > + sector, min(len, front_pad) << SECTOR_SHIFT); > > + > > Is it possible to create different interface for discard and write > zeroes ? I think it is a lot of logic adding on one function if everyone > else is okay please discard my comment .. Copying code is anti-pattern - it increases code size and it makes it harder to modify code in the future. Discard and write-zeroes perform almost the same operation, the only difference is that write-zeroes needs to zero trailing and leading parts of boundary pages. Therefore I think that making one function that performs both discard and write zeroes is ok. > > - if (bio_op(bio) == REQ_OP_DISCARD) { > > + if (bio_op(bio) == REQ_OP_DISCARD || > > + bio_op(bio) == REQ_OP_WRITE_ZEROES) { > > brd_do_discard(brd, bio); > > goto endio; > > } > > can we please use switch ? unless there is a strong need for if > which I failed to understand ... Yes, I can do this change. > > @@ -355,7 +368,7 @@ MODULE_PARM_DESC(max_part, "Num Minors t > > > > static bool discard = false; > > module_param(discard, bool, 0444); > > -MODULE_PARM_DESC(discard, "Support discard"); > > +MODULE_PARM_DESC(discard, "Support discard and write zeroes"); > > > > write-zeroes and discards are both different req_op and they should have > a separate module parameter ... > > above should be moved to new module parameter write_zeroes, unless there > is a reason to use one module parameter for both req_op... Is there some reason why the user might want discard and not want write-zeroes or vice versa? What do Christoph and Jens think? Do you think that there should be two separate parameters too? Mikulas
Index: linux-2.6/drivers/block/brd.c =================================================================== --- linux-2.6.orig/drivers/block/brd.c +++ linux-2.6/drivers/block/brd.c @@ -272,7 +272,8 @@ out: void brd_do_discard(struct brd_device *brd, struct bio *bio) { - sector_t sector, len, front_pad; + bool zero_padding = bio_op(bio) == REQ_OP_WRITE_ZEROES; + sector_t sector, len, front_pad, end_pad; if (unlikely(!discard)) { bio->bi_status = BLK_STS_NOTSUPP; @@ -282,11 +283,22 @@ void brd_do_discard(struct brd_device *b sector = bio->bi_iter.bi_sector; len = bio_sectors(bio); front_pad = -sector & (PAGE_SECTORS - 1); + + if (zero_padding && unlikely(front_pad != 0)) + copy_to_brd(brd, page_address(ZERO_PAGE(0)), + sector, min(len, front_pad) << SECTOR_SHIFT); + sector += front_pad; if (unlikely(len <= front_pad)) return; len -= front_pad; - len = round_down(len, PAGE_SECTORS); + + end_pad = len & (PAGE_SECTORS - 1); + if (zero_padding && unlikely(end_pad != 0)) + copy_to_brd(brd, page_address(ZERO_PAGE(0)), + sector + len - end_pad, end_pad << SECTOR_SHIFT); + len -= end_pad; + while (len) { brd_free_page(brd, sector); sector += PAGE_SECTORS; @@ -302,7 +314,8 @@ static void brd_submit_bio(struct bio *b struct bio_vec bvec; struct bvec_iter iter; - if (bio_op(bio) == REQ_OP_DISCARD) { + if (bio_op(bio) == REQ_OP_DISCARD || + bio_op(bio) == REQ_OP_WRITE_ZEROES) { brd_do_discard(brd, bio); goto endio; } @@ -355,7 +368,7 @@ MODULE_PARM_DESC(max_part, "Num Minors t static bool discard = false; module_param(discard, bool, 0444); -MODULE_PARM_DESC(discard, "Support discard"); +MODULE_PARM_DESC(discard, "Support discard and write zeroes"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); @@ -425,6 +438,7 @@ static int brd_alloc(int i) if (discard) { disk->queue->limits.discard_granularity = PAGE_SIZE; blk_queue_max_discard_sectors(disk->queue, round_down(UINT_MAX, PAGE_SECTORS)); + blk_queue_max_write_zeroes_sectors(disk->queue, round_down(UINT_MAX, PAGE_SECTORS)); } /* Tell the block layer that this is not a rotational device */
This patch implements REQ_OP_WRITE_ZEROES on brd. Write zeroes will free the pages just like discard, but the difference is that it writes zeroes to the preceding and following page if the range is not aligned on page boundary. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> --- drivers/block/brd.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)