Re: [PATCH] FUSE: Improve aio directIO write performance for size extending writes.

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] FUSE: Improve aio directIO write performance for size extending writes.

Ashish Sangwan
*ping*

Last time it bounced off the fuse mailing list.

On Thu, Apr 7, 2016 at 5:18 PM, Ashish Sangwan <[hidden email]> wrote:

> While sending the blocking directIO in fuse, the write request is broken
> into sub-requests, each of default size 128k and all the requests are sent
> in non-blocking background mode if async_dio mode is supported by libfuse.
> The process which issue the write wait for the completion of all the
> sub-requests. Sending multiple requests parallely gives a chance to perform
> parallel writes in the user space fuse implementation if it is
> multi-threaded and hence improves the performance.
>
> When there is a size extending aio dio write, we switch to
> blocking mode so that we can properly update the size of the file after
> completion of the writes. However, in this situation all the sub-requests
> are sent in serialized manner where the next request is sent only after
> receiving the reply of the current request. Hence the multi-threaded user
> space implementation is not utilized properly.
>
> This patch changes the size extending aio dio behavior to exactly follow
> blocking dio. For multi threaded fuse implementation having 10 threads and
> using buffer size of 64MB to perform async directIO, we are getting double
> the speed.
>
> Signed-off-by: Ashish Sangwan <[hidden email]>
> ---
>  fs/fuse/file.c   |   16 ++++++++--------
>  fs/fuse/fuse_i.h |    1 +
>  2 files changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> index 9dde38f..b4f8b83 100644
> --- a/fs/fuse/file.c
> +++ b/fs/fuse/file.c
> @@ -572,11 +572,11 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
>                 io->bytes = pos;
>
>         left = --io->reqs;
> -       if (!left && is_sync)
> +       if (!left && (is_sync || io->blocking_aio))
>                 complete(io->done);
>         spin_unlock(&io->lock);
>
> -       if (!left && !is_sync) {
> +       if (!left && !is_sync && !io->blocking_aio) {
>                 ssize_t res = fuse_get_res_by_io(io);
>
>                 if (res >= 0) {
> @@ -2884,17 +2884,17 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
>          */
>         io->async = async_dio;
>         io->iocb = iocb;
> +       io->blocking_aio = false;
>
>         /*
> -        * We cannot asynchronously extend the size of a file. We have no method
> -        * to wait on real async I/O requests, so we must submit this request
> -        * synchronously.
> +        * We cannot asynchronously extend the size of a file.
> +        * In such case the aio will behave exactly like sync io.
>          */
>         if (!is_sync && (offset + count > i_size) &&
>             iov_iter_rw(iter) == WRITE)
> -               io->async = false;
> +               io->blocking_aio = true;
>
> -       if (io->async && is_sync) {
> +       if (io->async && (is_sync | io->blocking_aio)) {
>                 /*
>                  * Additional reference to keep io around after
>                  * calling fuse_aio_complete()
> @@ -2914,7 +2914,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
>                 fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
>
>                 /* we have a non-extending, async request, so return */
> -               if (!is_sync)
> +               if (!is_sync && !io->blocking_aio)
>                         return -EIOCBQUEUED;
>
>                 wait_for_completion(&wait);
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index eddbe02..a7cf03f 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -256,6 +256,7 @@ struct fuse_io_priv {
>         struct kiocb *iocb;
>         struct file *file;
>         struct completion *done;
> +       bool blocking_aio;
>  };
>
>  #define FUSE_IO_PRIV_SYNC(f) \
> --
> 1.7.9.5
>

------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
--
fuse-devel mailing list
To unsubscribe or subscribe, visit https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] FUSE: Improve aio directIO write performance for size extending writes.

Ashish Sangwan
Hi Miklos,

Did you get any time to look into the patch?
Its been more than two months.

On Thu, Apr 14, 2016 at 6:02 PM, Ashish Sangwan
<[hidden email]> wrote:

> *ping*
>
> Last time it bounced off the fuse mailing list.
>
> On Thu, Apr 7, 2016 at 5:18 PM, Ashish Sangwan <[hidden email]> wrote:
>> While sending the blocking directIO in fuse, the write request is broken
>> into sub-requests, each of default size 128k and all the requests are sent
>> in non-blocking background mode if async_dio mode is supported by libfuse.
>> The process which issue the write wait for the completion of all the
>> sub-requests. Sending multiple requests parallely gives a chance to perform
>> parallel writes in the user space fuse implementation if it is
>> multi-threaded and hence improves the performance.
>>
>> When there is a size extending aio dio write, we switch to
>> blocking mode so that we can properly update the size of the file after
>> completion of the writes. However, in this situation all the sub-requests
>> are sent in serialized manner where the next request is sent only after
>> receiving the reply of the current request. Hence the multi-threaded user
>> space implementation is not utilized properly.
>>
>> This patch changes the size extending aio dio behavior to exactly follow
>> blocking dio. For multi threaded fuse implementation having 10 threads and
>> using buffer size of 64MB to perform async directIO, we are getting double
>> the speed.
>>
>> Signed-off-by: Ashish Sangwan <[hidden email]>
>> ---
>>  fs/fuse/file.c   |   16 ++++++++--------
>>  fs/fuse/fuse_i.h |    1 +
>>  2 files changed, 9 insertions(+), 8 deletions(-)
>>
>> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
>> index 9dde38f..b4f8b83 100644
>> --- a/fs/fuse/file.c
>> +++ b/fs/fuse/file.c
>> @@ -572,11 +572,11 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
>>                 io->bytes = pos;
>>
>>         left = --io->reqs;
>> -       if (!left && is_sync)
>> +       if (!left && (is_sync || io->blocking_aio))
>>                 complete(io->done);
>>         spin_unlock(&io->lock);
>>
>> -       if (!left && !is_sync) {
>> +       if (!left && !is_sync && !io->blocking_aio) {
>>                 ssize_t res = fuse_get_res_by_io(io);
>>
>>                 if (res >= 0) {
>> @@ -2884,17 +2884,17 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
>>          */
>>         io->async = async_dio;
>>         io->iocb = iocb;
>> +       io->blocking_aio = false;
>>
>>         /*
>> -        * We cannot asynchronously extend the size of a file. We have no method
>> -        * to wait on real async I/O requests, so we must submit this request
>> -        * synchronously.
>> +        * We cannot asynchronously extend the size of a file.
>> +        * In such case the aio will behave exactly like sync io.
>>          */
>>         if (!is_sync && (offset + count > i_size) &&
>>             iov_iter_rw(iter) == WRITE)
>> -               io->async = false;
>> +               io->blocking_aio = true;
>>
>> -       if (io->async && is_sync) {
>> +       if (io->async && (is_sync | io->blocking_aio)) {
>>                 /*
>>                  * Additional reference to keep io around after
>>                  * calling fuse_aio_complete()
>> @@ -2914,7 +2914,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
>>                 fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
>>
>>                 /* we have a non-extending, async request, so return */
>> -               if (!is_sync)
>> +               if (!is_sync && !io->blocking_aio)
>>                         return -EIOCBQUEUED;
>>
>>                 wait_for_completion(&wait);
>> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
>> index eddbe02..a7cf03f 100644
>> --- a/fs/fuse/fuse_i.h
>> +++ b/fs/fuse/fuse_i.h
>> @@ -256,6 +256,7 @@ struct fuse_io_priv {
>>         struct kiocb *iocb;
>>         struct file *file;
>>         struct completion *done;
>> +       bool blocking_aio;
>>  };
>>
>>  #define FUSE_IO_PRIV_SYNC(f) \
>> --
>> 1.7.9.5
>>

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
--
fuse-devel mailing list
To unsubscribe or subscribe, visit https://lists.sourceforge.net/lists/listinfo/fuse-devel