Message ID | ee72e7d0-e885-7b0a-b9cc-6572b0614c20@kernel.dk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 11/16/2016 01:36 PM, Jens Axboe wrote: > On 11/16/2016 01:02 PM, Jens Axboe wrote: >> On 11/16/2016 10:16 AM, Christoph Hellwig wrote: >>> I've pushed out a new version of my code that avoids atomic ops >>> for the single bio case: >>> >>> http://git.infradead.org/users/hch/block.git/shortlog/refs/heads/new-dio >>> >>> I think we should take your extension of the existing >>> __blkdev_direct_IO_simple to kmalloc up to BIO_MAX_PAGES and then use >>> the above implementation for AIO and large synchronous I/O. >>> >>> I think I can also kill of blkdev_dio_pool by simply using bio_kmalloc >>> as we're only doing the allocation at the beginning of the call, >>> but I'd like to agree on an approach before spending too much time on >>> it. >>> >> >> I'm fine with this approach, but I would still REALLY like to see >> blkdev_bio_end_io() split in two, once for sync and once for async. That >> would be a lot cleaner, imho. >> >> Let me know how you want to do it. I added SYNC support for mine here, >> the branch is here: >> >> http://git.kernel.dk/cgit/linux-block/log/?h=for-4.10/dio > > Attaching two patches here that add the BIO_MAX_PAGES extension, and the > SYNC support for your branch. Latter is untested... You can add my > reviewed-by to: > > 7bed5be4f28cc86e3929c0c0fbba24ca0344f36c > 57c2cf5c2595c0054855d7402d3796b5924fd05c > > I'd like to get this in for 4.10. Tested the cache flush part, seems to work fine as well for both sync and async O_DIRECT.
On 11/16/2016 01:51 PM, Jens Axboe wrote: > On 11/16/2016 01:36 PM, Jens Axboe wrote: >> On 11/16/2016 01:02 PM, Jens Axboe wrote: >>> On 11/16/2016 10:16 AM, Christoph Hellwig wrote: >>>> I've pushed out a new version of my code that avoids atomic ops >>>> for the single bio case: >>>> >>>> http://git.infradead.org/users/hch/block.git/shortlog/refs/heads/new-dio >>>> >>>> >>>> I think we should take your extension of the existing >>>> __blkdev_direct_IO_simple to kmalloc up to BIO_MAX_PAGES and then use >>>> the above implementation for AIO and large synchronous I/O. >>>> >>>> I think I can also kill of blkdev_dio_pool by simply using bio_kmalloc >>>> as we're only doing the allocation at the beginning of the call, >>>> but I'd like to agree on an approach before spending too much time on >>>> it. >>>> >>> >>> I'm fine with this approach, but I would still REALLY like to see >>> blkdev_bio_end_io() split in two, once for sync and once for async. That >>> would be a lot cleaner, imho. >>> >>> Let me know how you want to do it. I added SYNC support for mine here, >>> the branch is here: >>> >>> http://git.kernel.dk/cgit/linux-block/log/?h=for-4.10/dio >> >> Attaching two patches here that add the BIO_MAX_PAGES extension, and the >> SYNC support for your branch. Latter is untested... You can add my >> reviewed-by to: >> >> 7bed5be4f28cc86e3929c0c0fbba24ca0344f36c >> 57c2cf5c2595c0054855d7402d3796b5924fd05c >> >> I'd like to get this in for 4.10. > > Tested the cache flush part, seems to work fine as well for both sync > and async O_DIRECT. Updated the last patch, since it had both a typo in the subject line and some duplicated code after I added the dio_should_flush_cache() helper. Top two patches here: http://git.kernel.dk/cgit/linux-block/log/?h=for-4.10/hch-dio which is on top of your dio branch.
From 84629aca0c25cab79b2e03f2e046b5691255bf17 Mon Sep 17 00:00:00 2001 From: Jens Axboe <axboe@fb.com> Date: Mon, 14 Nov 2016 10:19:47 -0700 Subject: [PATCH 1/2] block: support any sized IO for simplified bdev direct-io Just alloc the bio_vec array if we exceed the inline limit. Signed-off-by: Jens Axboe <axboe@fb.com> --- fs/block_dev.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 6c8b6dfac1e5..d34ec663f538 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -193,7 +193,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, struct file *file = iocb->ki_filp; struct block_device *bdev = I_BDEV(bdev_file_inode(file)); unsigned blkbits = blksize_bits(bdev_logical_block_size(bdev)); - struct bio_vec inline_vecs[DIO_INLINE_BIO_VECS], *bvec; + struct bio_vec inline_vecs[DIO_INLINE_BIO_VECS], *vecs, *bvec; loff_t pos = iocb->ki_pos; bool should_dirty = false; struct bio bio; @@ -204,9 +204,17 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, if ((pos | iov_iter_alignment(iter)) & ((1 << blkbits) - 1)) return -EINVAL; + if (nr_pages <= DIO_INLINE_BIO_VECS) + vecs = inline_vecs; + else { + vecs = kmalloc(nr_pages * sizeof(struct bio_vec), GFP_KERNEL); + if (!vecs) + return -ENOMEM; + } + bio_init(&bio); bio.bi_max_vecs = nr_pages; - bio.bi_io_vec = inline_vecs; + bio.bi_io_vec = vecs; bio.bi_bdev = bdev; bio.bi_iter.bi_sector = pos >> blkbits; bio.bi_private = current; @@ -243,6 +251,9 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, put_page(bvec->bv_page); } + if (vecs != inline_vecs) + kfree(vecs); + if (unlikely(bio.bi_error)) return bio.bi_error; iocb->ki_pos += ret; @@ -408,7 +419,7 @@ blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES); if (!nr_pages) return 0; - if (is_sync_kiocb(iocb) && nr_pages <= DIO_INLINE_BIO_VECS) + if (is_sync_kiocb(iocb)) return __blkdev_direct_IO_simple(iocb, iter, nr_pages); return __blkdev_direct_IO(iocb, iter, nr_pages); } -- 2.7.4