From patchwork Fri Nov 30 19:58:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 10707091 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A8CB1057 for ; Fri, 30 Nov 2018 19:58:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2E29030453 for ; Fri, 30 Nov 2018 19:58:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 223F3304F0; Fri, 30 Nov 2018 19:58:33 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 BE79430453 for ; Fri, 30 Nov 2018 19:58:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727072AbeLAHIp (ORCPT ); Sat, 1 Dec 2018 02:08:45 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:34490 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726808AbeLAHIo (ORCPT ); Sat, 1 Dec 2018 02:08:44 -0500 Received: by mail-yb1-f194.google.com with SMTP id a67-v6so2720899ybg.1 for ; Fri, 30 Nov 2018 11:58:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=ZiSWalXRo2lAHNoxFcnCBmYqM80BUgBK6TZ//qlBoW0=; b=qE17nE2Jo3x4abm13SJxAAIFGmnZyoF8C/6nu8aRpvS4rDGOAT+NB7nFb5qR/q9r0W wyEq3cqlr+cDklN/eobicAnmyPZ5O00B6CLcEWwkMfbaQv2f1e/zarf+qIW/wPERWt9z QGzxh3p+tv3y8zML5KreAJ0J0fdK1gQiiTp1jNjrMW9vgTdx5CDjGysHbm7NtzHtqj2z G48SlfhBIGMBXljirIlfet56WObqccekan4prBch/7ywFpwIc9gEWxYUBnEKPj4xUmnP p7oYI1XwYAfhLaNWOYg0r74CjigClE0qUNLmKqCBjSEdRHgY4p9ac7AqgtmRfyHOfhUM 7DqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=ZiSWalXRo2lAHNoxFcnCBmYqM80BUgBK6TZ//qlBoW0=; b=oz8xGFl2o2JNMrroBQgCEcnKNTTnM8TTqMb23sC8r3EzberpiOBz1mhrobzugZ2jQG TGlQ26u67/pGDIo3NlRM2hHyE/6BYST6wj+UDm6G8vbLSq8iFj0pKrywP7H+bi3Bz7Ck drXNmSOApRRL/HDt+OtxErcSBmRnqmfmLW5JE0+Uj/UF3rt1mD14w/7135Ut6aZ5BFTN mD0vwh5x6tLjKOZdWLGGFnh7kAOipfmn853exiOPEoquoR2RUtPTUkYGKBh4drU3qo0K OzsOIOpivFLdsid0kTTRrmx/Q5yG88CSe1tqnQpiQeT+mzOPFOhZOEpScizAq+l8GFi3 Q03A== X-Gm-Message-State: AA+aEWZPocxlJEnWN7VZIDFh8yZNWF+VyfKWtScRzrCKEibXkrRmqOLg hverR+qRRqMzX1Mr94vzk/BqQg== X-Google-Smtp-Source: AFSGD/WUySeblOm5lO6iEZroC7YfnS5osaYyKXSy7/i64tvWyXdByqa0y4VKPk5GYCaEeI3VijK3IQ== X-Received: by 2002:a5b:b09:: with SMTP id z9-v6mr6591976ybp.483.1543607900825; Fri, 30 Nov 2018 11:58:20 -0800 (PST) Received: from localhost ([107.15.81.208]) by smtp.gmail.com with ESMTPSA id z74sm3209536ywz.51.2018.11.30.11.58.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 30 Nov 2018 11:58:20 -0800 (PST) From: Josef Bacik To: kernel-team@fb.com, hannes@cmpxchg.org, linux-kernel@vger.kernel.org, tj@kernel.org, david@fromorbit.com, akpm@linux-foundation.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, riel@redhat.com, jack@suse.cz Subject: [PATCH 4/4] mm: use the cached page for filemap_fault Date: Fri, 30 Nov 2018 14:58:12 -0500 Message-Id: <20181130195812.19536-5-josef@toxicpanda.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20181130195812.19536-1-josef@toxicpanda.com> References: <20181130195812.19536-1-josef@toxicpanda.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If we drop the mmap_sem we have to redo the vma lookup which requires redoing the fault handler. Chances are we will just come back to the same page, so save this page in our vmf->cached_page and reuse it in the next loop through the fault handler. Signed-off-by: Josef Bacik --- mm/filemap.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 5e76b24b2a0f..d4385b704e04 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2392,6 +2392,35 @@ static struct file *do_async_mmap_readahead(struct vm_area_struct *vma, return fpin; } +static int vmf_has_cached_page(struct vm_fault *vmf, struct page **page) +{ + struct page *cached_page = vmf->cached_page; + struct mm_struct *mm = vmf->vma->vm_mm; + struct address_space *mapping = vmf->vma->vm_file->f_mapping; + pgoff_t offset = vmf->pgoff; + + if (!cached_page) + return 0; + + if (vmf->flags & FAULT_FLAG_KILLABLE) { + int ret = lock_page_killable(cached_page); + if (ret) { + up_read(&mm->mmap_sem); + return ret; + } + } else + lock_page(cached_page); + vmf->cached_page = NULL; + if (cached_page->mapping == mapping && + cached_page->index == offset) { + *page = cached_page; + } else { + unlock_page(cached_page); + put_page(cached_page); + } + return 0; +} + /** * filemap_fault - read in file data for page fault handling * @vmf: struct vm_fault containing details of the fault @@ -2425,13 +2454,24 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) struct inode *inode = mapping->host; pgoff_t offset = vmf->pgoff; pgoff_t max_off; - struct page *page; + struct page *page = NULL; vm_fault_t ret = 0; max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); if (unlikely(offset >= max_off)) return VM_FAULT_SIGBUS; + /* + * We may have read in the page already and have a page from an earlier + * loop. If so we need to see if this page is still valid, and if not + * do the whole dance over again. + */ + error = vmf_has_cached_page(vmf, &page); + if (error) + goto out_retry; + if (page) + goto have_cached_page; + /* * Do we have something in the page cache already? */ @@ -2492,6 +2532,7 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) put_page(page); goto retry_find; } +have_cached_page: VM_BUG_ON_PAGE(page->index != offset, page); /* @@ -2558,7 +2599,7 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) * page. */ if (page) - put_page(page); + vmf->cached_page = page; if (fpin) fput(fpin); return ret | VM_FAULT_RETRY;