From patchwork Wed Jul 19 22:09:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 9853279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 83859602BD for ; Wed, 19 Jul 2017 22:10:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7552A285EA for ; Wed, 19 Jul 2017 22:10:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A3A728717; Wed, 19 Jul 2017 22:10:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0970D285EA for ; Wed, 19 Jul 2017 22:10:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753904AbdGSWKR (ORCPT ); Wed, 19 Jul 2017 18:10:17 -0400 Received: from mail-it0-f68.google.com ([209.85.214.68]:35324 "EHLO mail-it0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755272AbdGSWKQ (ORCPT ); Wed, 19 Jul 2017 18:10:16 -0400 Received: by mail-it0-f68.google.com with SMTP id v127so855150itd.2 for ; Wed, 19 Jul 2017 15:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=I76OvF8Idm1JRBTJSFOkqJbyocjDjZo4zWlj4c8ovu8=; b=a4qiTEtTYmXptIee9ffSMcV7hdNFhIwuL/CwZ42zixpORUa/n/PZ1xgqpY4QEIgaSY 5XFiNNWIXXRzdWGSlqCAf9XGDoLUmAT+3RdY4xDxdfQg7aDHV5BWY12ACXspRp4shKmh 5g+LpXqT6lta8XWmLeQJy/ESgGwgwbOzMWJ3TR0deg5B0JKzH1LgyaJniE2fq7sbZfrG SpeiGvHGnaQjZ3TXwKeMbcao27Aksx8zozgH9bJMOElDhOMN614drGfXk7MIUJQw/deD N1x0DWWG47guLfja7yRw2kYagK/1mGbsqm3S6p9O093mVu03UFRIXEsSNL2MEAVcWta3 cZdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=I76OvF8Idm1JRBTJSFOkqJbyocjDjZo4zWlj4c8ovu8=; b=q9h2reJQLrrlJhzMFQcZXPN68COULFikOXWxjhyYKu5XqJwHs179zoBo1v4a7nHtqf SLtBn88B8Wiy1a0UFgVhO507OPt8pmn7yCfnwSYJFa2V6kBL5jtXNvAyQWa42J0e4gPC MftgC99Zjg3TV5VSa/3DIEZVaQWz/lEbFqO8WXFN9JzVRv4jdnzzmqgMWFLnCEKn8E2/ KF4GMnK42s22zULjuc7gUR9mBE7G2XztgzAwCHxwFofnUE+9GShBUw4LkZ/IPYFtMQKq prduTwCsb/1Fzqe11HOFZKNPGMTmEhV0Sxfm6Ay2DhgGEOc2UVGTaHNwOx5kJe+LVupH 6yig== X-Gm-Message-State: AIVw110AkiYNBMYuGYrE0k5L1bejCtRB1JvOEQ/o6TvBh6vTjDvYOGk2 gxSQUldzTPKDaO3c6b4= X-Received: by 10.36.110.23 with SMTP id w23mr1508908itc.24.1500502215407; Wed, 19 Jul 2017 15:10:15 -0700 (PDT) Received: from leira.trondhjem.org (c-68-49-162-121.hsd1.mi.comcast.net. [68.49.162.121]) by smtp.gmail.com with ESMTPSA id 9sm518333iop.9.2017.07.19.15.10.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 19 Jul 2017 15:10:14 -0700 (PDT) From: Trond Myklebust To: Chuck Lever , linux-nfs@vger.kernel.org Subject: [PATCH 13/20] NFS: Further optimise nfs_lock_and_join_requests() Date: Wed, 19 Jul 2017 18:09:48 -0400 Message-Id: <20170719220955.58210-14-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170719220955.58210-13-trond.myklebust@primarydata.com> References: <20170719220955.58210-1-trond.myklebust@primarydata.com> <20170719220955.58210-2-trond.myklebust@primarydata.com> <20170719220955.58210-3-trond.myklebust@primarydata.com> <20170719220955.58210-4-trond.myklebust@primarydata.com> <20170719220955.58210-5-trond.myklebust@primarydata.com> <20170719220955.58210-6-trond.myklebust@primarydata.com> <20170719220955.58210-7-trond.myklebust@primarydata.com> <20170719220955.58210-8-trond.myklebust@primarydata.com> <20170719220955.58210-9-trond.myklebust@primarydata.com> <20170719220955.58210-10-trond.myklebust@primarydata.com> <20170719220955.58210-11-trond.myklebust@primarydata.com> <20170719220955.58210-12-trond.myklebust@primarydata.com> <20170719220955.58210-13-trond.myklebust@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When locking the entire group in order to remove subrequests, the locks are always taken in order, and with the page group lock being taken after the page head is locked. The intention is that: 1) The lock on the group head guarantees that requests may not be removed from the group (although new entries could be appended if we're not holding the group lock). 2) It is safe to drop and retake the page group lock while iterating through the list, in particular when waiting for a subrequest lock. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ff7c90c7ff79..1ee5d89380d9 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -377,31 +377,17 @@ nfs_page_group_clear_bits(struct nfs_page *req) * * returns 0 on success, < 0 on error. */ -static int -nfs_unroll_locks_and_wait(struct inode *inode, struct nfs_page *head, +static void +nfs_unroll_locks(struct inode *inode, struct nfs_page *head, struct nfs_page *req) { struct nfs_page *tmp; - int ret; /* relinquish all the locks successfully grabbed this run */ for (tmp = head->wb_this_page ; tmp != req; tmp = tmp->wb_this_page) nfs_unlock_request(tmp); WARN_ON_ONCE(test_bit(PG_TEARDOWN, &req->wb_flags)); - - /* grab a ref on the request that will be waited on */ - kref_get(&req->wb_kref); - - nfs_page_group_unlock(head); - - /* release ref from nfs_page_find_head_request_locked */ - nfs_unlock_and_release_request(head); - - ret = nfs_wait_on_request(req); - nfs_release_request(req); - - return ret; } /* @@ -525,18 +511,21 @@ nfs_lock_and_join_requests(struct page *page) total_bytes = head->wb_bytes; for (subreq = head->wb_this_page; subreq != head; subreq = subreq->wb_this_page) { - if (!nfs_lock_request(subreq)) { + + while (!nfs_lock_request(subreq)) { /* - * releases page group bit lock and - * page locks and all references + * Unlock page to allow nfs_page_group_sync_on_bit() + * to succeed */ - ret = nfs_unroll_locks_and_wait(inode, head, - subreq); - - if (ret == 0) - goto try_again; - - return ERR_PTR(ret); + nfs_page_group_unlock(head); + ret = nfs_wait_on_request(subreq); + if (!ret) + ret = nfs_page_group_lock(head, false); + if (ret < 0) { + nfs_unroll_locks(inode, head, subreq); + nfs_unlock_and_release_request(head); + return ERR_PTR(ret); + } } /* * Subrequests are always contiguous, non overlapping @@ -549,7 +538,9 @@ nfs_lock_and_join_requests(struct page *page) ((subreq->wb_offset + subreq->wb_bytes) > (head->wb_offset + total_bytes)))) { nfs_unlock_request(subreq); - nfs_unroll_locks_and_wait(inode, head, subreq); + nfs_unroll_locks(inode, head, subreq); + nfs_page_group_unlock(head); + nfs_unlock_and_release_request(head); return ERR_PTR(-EIO); } }