From patchwork Thu Aug 3 13:45:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 9879197 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 372E560360 for ; Thu, 3 Aug 2017 13:47:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C83C25F31 for ; Thu, 3 Aug 2017 13:47:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 21526288EF; Thu, 3 Aug 2017 13:47:18 +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 1CD27287B2 for ; Thu, 3 Aug 2017 13:47:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751987AbdHCNqd (ORCPT ); Thu, 3 Aug 2017 09:46:33 -0400 Received: from mail-it0-f65.google.com ([209.85.214.65]:33219 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751879AbdHCNpv (ORCPT ); Thu, 3 Aug 2017 09:45:51 -0400 Received: by mail-it0-f65.google.com with SMTP id m34so1323023iti.0 for ; Thu, 03 Aug 2017 06:45:51 -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=ijxn5ktG/idCBd/ORj6cx04+wZNctpv67WP8Wiwd5JGPJMj5ShER2tweQGzJYwTAyR gBLQZrW0/I5d5ArLahX/85JI358BZTFO5XbypyhC62YlVHChDANfZDw3RtSV1RUd6gsC jkvIVEYiSYUPUceILP6G5aicI9MT5C3InU+9Y2sQM1JipHBwuuDGUiPrhji1pxTEpXQP BUBYscTp1PjHiVmfLXA+bAsNGIVHUo2+yDS2+US6h4T80uj38oa83lBR0XeRcmdpApsY tedHitQTstSf+VnlBSBlWrZVvzneZjZi4bh5u97Wr8zQjdic4IzCpd+rqwkJwDsTkaee vqAA== 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=BcxmS7lHmgcKvwJmuaCFHIA40nkWk5wdP8mmtG30uhSf8Z9TaXuAdygQu9iJgq1lpK 2gstdFBlmQCgQPE4nn5Nop+A2iJC5lVr6etL48+M+RlLBJFCPq8mE1XMsVuzPtxMgEBK bfjwFeSFufyJqkoLlQ7XPHdQEfRpeu60ZHXqNQNQQ5ogzyRQKVBx3MDRn/t3OL7OgMuq weNPgsoACh/ufgGvoD0stGreIKDJoSws3MpcOx5mvzbqzd0ldTZTyGqEQ3U93iZHthww XsTNUjNYtV2Y3PR4jhznmiLHcK3lYFk/1N44SQyc0ifkj8XUwRigaNQO/Nentwn/HRYT gTGg== X-Gm-Message-State: AIVw112HnQ5mBnh0gZmEV34VZRqSYOdfzMcPumvjb/HiPSVVWxCF4kIF N3dtAhUTA7JT4RcPBRw= X-Received: by 10.36.127.67 with SMTP id r64mr1919817itc.78.1501767950694; Thu, 03 Aug 2017 06:45:50 -0700 (PDT) Received: from localhost.localdomain (50-108-95-251.adr01.mskg.mi.frontiernet.net. [50.108.95.251]) by smtp.gmail.com with ESMTPSA id q90sm5759547ioi.41.2017.08.03.06.45.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Aug 2017 06:45:50 -0700 (PDT) From: Trond Myklebust To: Chuck Lever , linux-nfs@vger.kernel.org Subject: [PATCH v2 13/28] NFS: Further optimise nfs_lock_and_join_requests() Date: Thu, 3 Aug 2017 09:45:08 -0400 Message-Id: <20170803134523.4922-14-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170803134523.4922-13-trond.myklebust@primarydata.com> References: <20170803134523.4922-1-trond.myklebust@primarydata.com> <20170803134523.4922-2-trond.myklebust@primarydata.com> <20170803134523.4922-3-trond.myklebust@primarydata.com> <20170803134523.4922-4-trond.myklebust@primarydata.com> <20170803134523.4922-5-trond.myklebust@primarydata.com> <20170803134523.4922-6-trond.myklebust@primarydata.com> <20170803134523.4922-7-trond.myklebust@primarydata.com> <20170803134523.4922-8-trond.myklebust@primarydata.com> <20170803134523.4922-9-trond.myklebust@primarydata.com> <20170803134523.4922-10-trond.myklebust@primarydata.com> <20170803134523.4922-11-trond.myklebust@primarydata.com> <20170803134523.4922-12-trond.myklebust@primarydata.com> <20170803134523.4922-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); } }