From patchwork Thu Apr 7 11:48:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashish Sangwan X-Patchwork-Id: 8771371 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9D1DBC0553 for ; Thu, 7 Apr 2016 11:48:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AD6BC20204 for ; Thu, 7 Apr 2016 11:48:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AD374201BB for ; Thu, 7 Apr 2016 11:48:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756019AbcDGLsx (ORCPT ); Thu, 7 Apr 2016 07:48:53 -0400 Received: from mail-pa0-f67.google.com ([209.85.220.67]:34677 "EHLO mail-pa0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755861AbcDGLsv (ORCPT ); Thu, 7 Apr 2016 07:48:51 -0400 Received: by mail-pa0-f67.google.com with SMTP id hb4so6670778pac.1; Thu, 07 Apr 2016 04:48:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=rx4EllxFSZt7IyRyhZIeoNIDmZgVTinPN7P1vGOo3Zc=; b=dzqm/ruIjbBroRLIZ1zlwQ7Joe3JfYcf1Qwhg7CKPBusONM6VcuWxEuLIV9bVoMCeW qhhTHaR+st/qcgj5RhL2cPUZ7TpettP/wCqxP/KCYjM7zf/2nLe5N2XgWfNglL+MOSMM hUzL45l5UY2cfFjQA5jBwuBmpnJF9oJttLQUbywzVuY6Wiews1+tbUxNIeqFgJWu1YrG JRqLrUiSGChTW7um9QpIo279WrUwq3dNkOjozxJZ7b5uBsAMzZpSdvdWjz3q6aQL+5fw qemCujhS2JQkc1fb+rxgeU6n9497QjG4W0XBXT/FNgmXTlTbq/vOAF6fnnGMH3l6BKkJ KYTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rx4EllxFSZt7IyRyhZIeoNIDmZgVTinPN7P1vGOo3Zc=; b=NtWRtIbYffWqlB2V8SBmrtokb6WBtLb6Xnt+EZtJNbkPAm7rge9PfEQsRyrzvj/61o U0i6xNw1ejG+RsPI3fcDLEGz7fQuDjWnUbDJwfYNbDIkjbDdtWQj1x18vLgz4PMZsoUe dXSEJdMaXWiSaCXtRyIw7vcNF2HeqHkMzQGnFoPn8vjqcsWuQN21qCB1MWsk9xdPhb2q ocPCb6vKhy43e8462UiT+6qeEPuXa/X5bsvbMb9Oa1H95txqRgPxGzF7/bXd0aLbp/U+ P3XZHW5+ktPNNFVI4L7Ukrq6mz56+JIZhPP3Nj3VDkqgsTfVnnrYIAneGLb68GGnZa4s uwcg== X-Gm-Message-State: AD7BkJJf0aPkrLn7bouCvpxbB6xFUZMAbcSq5HSzGSjICIFZnwuM4aBSmA8JFHfUoneEJA== X-Received: by 10.66.250.199 with SMTP id ze7mr4163290pac.103.1460029730650; Thu, 07 Apr 2016 04:48:50 -0700 (PDT) Received: from ashish-pc.corp.maprtech.com ([14.142.27.186]) by smtp.gmail.com with ESMTPSA id ba9sm11752653pab.24.2016.04.07.04.48.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Apr 2016 04:48:49 -0700 (PDT) From: Ashish Sangwan To: Miklos Szeredi Cc: fuse-devel@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Ashish Sangwan Subject: [PATCH] FUSE: Improve aio directIO write performance for size extending writes. Date: Thu, 7 Apr 2016 17:18:11 +0530 Message-Id: <1460029691-7550-1-git-send-email-ashishsangwan2@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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) \