Message ID | 8e7975e44504d8371d716167face2bc8e248f7a4.1726072086.git.asml.silence@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | implement async block discards and other ops via io_uring | expand |
On Wed, Sep 11, 2024 at 05:34:42PM +0100, Pavel Begunkov wrote: > Add a second io_uring cmd for block layer implementing asynchronous > write zeroes. It reuses helpers we've added for async discards, and > inherits the code structure as well as all considerations in regards to > page cache races. It has to be supported by underlying hardware to be > used, otherwise the request will fail. A fallback version is implemented > separately in a later patch. Except that as far as I can tell it doesn't implement a fallback, but an entirely different command leading to applications breaking when just using the command and the hardware doesn't support it. Nacked-by: Christoph Hellwig <hch@lst.de> to this incomplete API that will just create incompatbilities.
On 9/12/24 10:32, Christoph Hellwig wrote: > On Wed, Sep 11, 2024 at 05:34:42PM +0100, Pavel Begunkov wrote: >> Add a second io_uring cmd for block layer implementing asynchronous >> write zeroes. It reuses helpers we've added for async discards, and >> inherits the code structure as well as all considerations in regards to >> page cache races. It has to be supported by underlying hardware to be >> used, otherwise the request will fail. A fallback version is implemented >> separately in a later patch. > > Except that as far as I can tell it doesn't implement a fallback, but I could've worded it better, but it doesn't say anything about implementing fallback for this opcode. > an entirely different command leading to applications breaking when > just using the command and the hardware doesn't support it. > > Nacked-by: Christoph Hellwig <hch@lst.de> > > to this incomplete API that will just create incompatbilities. That's fine, I'd rather take your nack than humouring the idea of having a worse api than it could be.
On 9/12/24 10:25 AM, Pavel Begunkov wrote: >> an entirely different command leading to applications breaking when >> just using the command and the hardware doesn't support it. >> >> Nacked-by: Christoph Hellwig <hch@lst.de> >> >> to this incomplete API that will just create incompatbilities. > > That's fine, I'd rather take your nack than humouring the idea > of having a worse api than it could be. How about we just drop 6-8 for now, and just focus on getting the actual main discard operation in? That's (by far) the most important anyway, and we can always add the write-zeroes bit later.
On 9/12/24 17:32, Jens Axboe wrote: > On 9/12/24 10:25 AM, Pavel Begunkov wrote: >>> an entirely different command leading to applications breaking when >>> just using the command and the hardware doesn't support it. >>> >>> Nacked-by: Christoph Hellwig <hch@lst.de> >>> >>> to this incomplete API that will just create incompatbilities. >> >> That's fine, I'd rather take your nack than humouring the idea >> of having a worse api than it could be. > > How about we just drop 6-8 for now, and just focus on getting the actual > main discard operation in? That's (by far) the most important anyway, > and we can always add the write-zeroes bit later. That's surely an option, and it's naturally up to you. But to be clear, unless there are some new good arguments, I don't buy those requested changes for 6-8 and refuse to go with it, that's just creating a mess of flags cancelling each other down the line.
On 9/12/24 10:53 AM, Pavel Begunkov wrote: > On 9/12/24 17:32, Jens Axboe wrote: >> On 9/12/24 10:25 AM, Pavel Begunkov wrote: >>>> an entirely different command leading to applications breaking when >>>> just using the command and the hardware doesn't support it. >>>> >>>> Nacked-by: Christoph Hellwig <hch@lst.de> >>>> >>>> to this incomplete API that will just create incompatbilities. >>> >>> That's fine, I'd rather take your nack than humouring the idea >>> of having a worse api than it could be. >> >> How about we just drop 6-8 for now, and just focus on getting the actual >> main discard operation in? That's (by far) the most important anyway, >> and we can always add the write-zeroes bit later. > > That's surely an option, and it's naturally up to you. Just trying to make forward progress - and since the actual discard is the most interesting bit (imho), seems silly to gate it on the latter bits. > But to be clear, unless there are some new good arguments, I don't > buy those requested changes for 6-8 and refuse to go with it, that's > just creating a mess of flags cancelling each other down the line. That's something to hash out, might be easier to do in person at LPC next week. For now I'll just drop 6-8.
On Thu, Sep 12, 2024 at 10:32:21AM -0600, Jens Axboe wrote: > How about we just drop 6-8 for now, and just focus on getting the actual > main discard operation in? That's (by far) the most important anyway, > and we can always add the write-zeroes bit later. Sounds fine to me.
diff --git a/block/ioctl.c b/block/ioctl.c index 007f6399de66..f8f6d6a71ff0 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -778,6 +778,69 @@ static void bio_cmd_bio_end_io(struct bio *bio) bio_put(bio); } +static int blkdev_cmd_write_zeroes(struct io_uring_cmd *cmd, + struct block_device *bdev, + uint64_t start, uint64_t len, bool nowait) +{ + struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd); + sector_t bs_mask = (bdev_logical_block_size(bdev) >> SECTOR_SHIFT) - 1; + sector_t limit = bdev_write_zeroes_sectors(bdev); + sector_t sector = start >> SECTOR_SHIFT; + sector_t nr_sects = len >> SECTOR_SHIFT; + struct bio *prev = NULL, *bio; + gfp_t gfp = nowait ? GFP_NOWAIT : GFP_KERNEL; + int err; + + if (!(file_to_blk_mode(cmd->file) & BLK_OPEN_WRITE)) + return -EBADF; + if (bdev_read_only(bdev)) + return -EPERM; + err = blk_validate_byte_range(bdev, start, len); + if (err) + return err; + + if (!limit) + return -EOPNOTSUPP; + /* + * Don't allow multi-bio non-blocking submissions as subsequent bios + * may fail but we won't get a direct indication of that. Normally, + * the caller should retry from a blocking context. + */ + if (nowait && nr_sects > limit) + return -EAGAIN; + + err = filemap_invalidate_pages(bdev->bd_mapping, start, + start + len - 1, nowait); + if (err) + return err; + + limit = min(limit, (UINT_MAX >> SECTOR_SHIFT) & ~bs_mask); + while (nr_sects) { + sector_t bio_sects = min(nr_sects, limit); + + bio = bio_alloc(bdev, 0, REQ_OP_WRITE_ZEROES|REQ_NOUNMAP, gfp); + if (!bio) + break; + if (nowait) + bio->bi_opf |= REQ_NOWAIT; + bio->bi_iter.bi_sector = sector; + bio->bi_iter.bi_size = bio_sects << SECTOR_SHIFT; + sector += bio_sects; + nr_sects -= bio_sects; + + prev = bio_chain_and_submit(prev, bio); + } + if (unlikely(!prev)) + return -EAGAIN; + if (unlikely(nr_sects)) + bic->res = -EAGAIN; + + prev->bi_private = cmd; + prev->bi_end_io = bio_cmd_bio_end_io; + submit_bio(prev); + return -EIOCBQUEUED; +} + static int blkdev_cmd_discard(struct io_uring_cmd *cmd, struct block_device *bdev, uint64_t start, uint64_t len, bool nowait) @@ -856,6 +919,9 @@ int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) switch (cmd_op) { case BLOCK_URING_CMD_DISCARD: return blkdev_cmd_discard(cmd, bdev, start, len, bic->nowait); + case BLOCK_URING_CMD_WRITE_ZEROES: + return blkdev_cmd_write_zeroes(cmd, bdev, start, len, + bic->nowait); } return -EINVAL; } diff --git a/include/uapi/linux/blkdev.h b/include/uapi/linux/blkdev.h index 66373cd1a83a..b4664139a82a 100644 --- a/include/uapi/linux/blkdev.h +++ b/include/uapi/linux/blkdev.h @@ -10,5 +10,6 @@ * It's a different number space from ioctl(), reuse the block's code 0x12. */ #define BLOCK_URING_CMD_DISCARD _IO(0x12, 0) +#define BLOCK_URING_CMD_WRITE_ZEROES _IO(0x12, 1) #endif
Add a second io_uring cmd for block layer implementing asynchronous write zeroes. It reuses helpers we've added for async discards, and inherits the code structure as well as all considerations in regards to page cache races. It has to be supported by underlying hardware to be used, otherwise the request will fail. A fallback version is implemented separately in a later patch. Suggested-by: Conrad Meyer <conradmeyer@meta.com> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> --- block/ioctl.c | 66 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/blkdev.h | 1 + 2 files changed, 67 insertions(+)