diff mbox

[PATCHSET] Add support for simplified async direct-io

Message ID ee72e7d0-e885-7b0a-b9cc-6572b0614c20@kernel.dk (mailing list archive)
State New, archived
Headers show

Commit Message

Jens Axboe Nov. 16, 2016, 8:36 p.m. UTC
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.

Comments

Jens Axboe Nov. 16, 2016, 8:51 p.m. UTC | #1
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.
Jens Axboe Nov. 17, 2016, 3:44 a.m. UTC | #2
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.
diff mbox

Patch

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