From patchwork Wed Nov 23 22:48:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13054435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AA86C433FE for ; Wed, 23 Nov 2022 22:48:48 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9CAB56B0075; Wed, 23 Nov 2022 17:48:47 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 97B0E6B0078; Wed, 23 Nov 2022 17:48:47 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8433D6B007B; Wed, 23 Nov 2022 17:48:47 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 74C9E6B0075 for ; Wed, 23 Nov 2022 17:48:47 -0500 (EST) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 4D2F7120B67 for ; Wed, 23 Nov 2022 22:48:47 +0000 (UTC) X-FDA: 80166198294.22.6DA85C2 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf30.hostedemail.com (Postfix) with ESMTP id EA10A80012 for ; Wed, 23 Nov 2022 22:48:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669243726; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qMSc8ri6PgRiNUl02Z6CVVLfho7VNuVLjNpxfTm/Xl8=; b=KogU8PHvhOGBtEIqDAHXxVLu/x1y09X7kVVsiSoAh7MLRLbvcHH3asLEjD/EefQwmtmMz8 0oPVkR2V/8MqukzQejX9Wsx1/0yNTnPBRkQZ+iUqJ5Jt+J8zEMta5s6U9xqQD+Is8Ge3nd PPATxgSkM+dLIS8EmrPW95mj39OPVUU= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-340-lAdP3-VPME-myi-_rt7VcA-1; Wed, 23 Nov 2022 17:48:41 -0500 X-MC-Unique: lAdP3-VPME-myi-_rt7VcA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F35AD3C0D193; Wed, 23 Nov 2022 22:48:40 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.14]) by smtp.corp.redhat.com (Postfix) with ESMTP id B64641400C38; Wed, 23 Nov 2022 22:48:38 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH v4 1/3] mm: Merge folio_has_private()/filemap_release_folio() call pairs From: David Howells To: Linus Torvalds Cc: Rohith Surabattula , Matthew Wilcox , Matthew Wilcox , Steve French , Shyam Prasad N , Rohith Surabattula , Dave Wysochanski , Dominique Martinet , Ilya Dryomov , linux-cachefs@redhat.com, linux-cifs@vger.kernel.org, linux-afs@lists.infradead.org, v9fs-developer@lists.sourceforge.net, ceph-devel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, dhowells@redhat.com, Matthew Wilcox , Jeff Layton , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-erofs@lists.ozlabs.org, linux-cachefs@redhat.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Wed, 23 Nov 2022 22:48:35 +0000 Message-ID: <166924371591.1772793.13893659228628027575.stgit@warthog.procyon.org.uk> In-Reply-To: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> References: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> User-Agent: StGit/1.5 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669243727; a=rsa-sha256; cv=none; b=rhD7pRX/Mmq0tsFbly1QNWUqsY/HCw6lXV74gsdv9cinyK+lgv70ECuZWJAy8i8bxx0lDF +yAzBrnW0FstnMagwMID8ropcq6pRDfVtd364T8ubcPFXuSxuYMEhesfpAg6uD0c1LX2u/ nY0DhLPsDnTaTol92wKDFDkzk07Z7p8= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=KogU8PHv; spf=pass (imf30.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669243727; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=qMSc8ri6PgRiNUl02Z6CVVLfho7VNuVLjNpxfTm/Xl8=; b=gv4OQO3lNDicC6s4QXkgHZfa2Vp4jO8pssUWF7b0feYB5CgfxXibQTY2wOiMvSk97yI+qI O8vP8X7bCcaYnepKeYAVVkQ+b/oQSxHZvbT+qmFFkIM9UDfxWSvzUybO3ZzIi8Fcje6Psd r2XJDbteNb5RIDqCmHTEJnNlj8Ot6jQ= X-Rspam-User: X-Rspamd-Queue-Id: EA10A80012 Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=KogU8PHv; spf=pass (imf30.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com X-Stat-Signature: zu8zukzibw3y8a33byqodix15b8k4dic X-Rspamd-Server: rspam10 X-HE-Tag: 1669243726-376300 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Make filemap_release_folio() check folio_has_private(). Then, in most cases, where a call to folio_has_private() is immediately followed by a call to filemap_release_folio(), we can get rid of the test in the pair. The same is done to page_has_private()/try_to_release_page() call pairs. There are a couple of sites in mm/vscan.c that this can't so easily be done. In shrink_folio_list(), there are actually three cases (something different is done for incompletely invalidated buffers), but filemap_release_folio() elides two of them. In shrink_active_list(), we don't have have the folio lock yet, so the check allows us to avoid locking the page unnecessarily. A wrapper function to check if a folio needs release is provided for those places that still need to do it in the mm/ directory. This will acquire additional parts to the condition in a future patch. Changes: ======== ver #4) - Split from fscache fix. - Moved folio_needs_release() to mm/internal.h and removed open-coded version from filemap_release_folio(). ver #3) - Fixed mapping_clear_release_always() to use clear_bit() not set_bit(). - Moved a '&&' to the correct line. ver #2) - Rewrote entirely according to Willy's suggestion[1]. Reported-by: Rohith Surabattula Suggested-by: Matthew Wilcox Signed-off-by: David Howells cc: Matthew Wilcox cc: Linus Torvalds cc: Steve French cc: Shyam Prasad N cc: Rohith Surabattula cc: Dave Wysochanski cc: Dominique Martinet cc: Ilya Dryomov cc: linux-cachefs@redhat.com cc: linux-cifs@vger.kernel.org cc: linux-afs@lists.infradead.org cc: v9fs-developer@lists.sourceforge.net cc: ceph-devel@vger.kernel.org cc: linux-nfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Link: https://lore.kernel.org/r/Yk9V/03wgdYi65Lb@casper.infradead.org/ [1] Link: https://lore.kernel.org/r/164928630577.457102.8519251179327601178.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/166844174069.1124521.10890506360974169994.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/166869495238.3720468.4878151409085146764.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/1459152.1669208550@warthog.procyon.org.uk/ # v3 also --- fs/splice.c | 3 +-- mm/filemap.c | 2 ++ mm/huge_memory.c | 3 +-- mm/internal.h | 8 ++++++++ mm/khugepaged.c | 3 +-- mm/memory-failure.c | 3 +-- mm/migrate.c | 3 +-- mm/truncate.c | 6 ++---- mm/vmscan.c | 7 +++---- 9 files changed, 20 insertions(+), 18 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 0878b852b355..563105304ccc 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -65,8 +65,7 @@ static bool page_cache_pipe_buf_try_steal(struct pipe_inode_info *pipe, */ folio_wait_writeback(folio); - if (folio_has_private(folio) && - !filemap_release_folio(folio, GFP_KERNEL)) + if (!filemap_release_folio(folio, GFP_KERNEL)) goto out_unlock; /* diff --git a/mm/filemap.c b/mm/filemap.c index 08341616ae7a..93757247cd11 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3941,6 +3941,8 @@ bool filemap_release_folio(struct folio *folio, gfp_t gfp) struct address_space * const mapping = folio->mapping; BUG_ON(!folio_test_locked(folio)); + if (!folio_needs_release(folio)) + return true; if (folio_test_writeback(folio)) return false; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 811d19b5c4f6..308d36aa3197 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2683,8 +2683,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) gfp = current_gfp_context(mapping_gfp_mask(mapping) & GFP_RECLAIM_MASK); - if (folio_test_private(folio) && - !filemap_release_folio(folio, gfp)) { + if (!filemap_release_folio(folio, gfp)) { ret = -EBUSY; goto out; } diff --git a/mm/internal.h b/mm/internal.h index 6b7ef495b56d..1fefb5181ab7 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -163,6 +163,14 @@ static inline void set_page_refcounted(struct page *page) set_page_count(page, 1); } +/* + * Return true if a folio needs ->release_folio() calling upon it. + */ +static inline bool folio_needs_release(struct folio *folio) +{ + return folio_has_private(folio); +} + extern unsigned long highest_memmap_pfn; /* diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 4734315f7940..7e9e0e3e678e 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1883,8 +1883,7 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, goto out_unlock; } - if (page_has_private(page) && - !try_to_release_page(page, GFP_KERNEL)) { + if (!try_to_release_page(page, GFP_KERNEL)) { result = SCAN_PAGE_HAS_PRIVATE; putback_lru_page(page); goto out_unlock; diff --git a/mm/memory-failure.c b/mm/memory-failure.c index bead6bccc7f2..82673fc01eed 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -831,8 +831,7 @@ static int truncate_error_page(struct page *p, unsigned long pfn, if (err != 0) { pr_info("%#lx: Failed to punch page: %d\n", pfn, err); - } else if (page_has_private(p) && - !try_to_release_page(p, GFP_NOIO)) { + } else if (!try_to_release_page(p, GFP_NOIO)) { pr_info("%#lx: failed to release buffers\n", pfn); } else { ret = MF_RECOVERED; diff --git a/mm/migrate.c b/mm/migrate.c index dff333593a8a..d721ef340943 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -905,8 +905,7 @@ static int fallback_migrate_folio(struct address_space *mapping, * Buffers may be managed in a filesystem specific way. * We must have no buffers or drop them. */ - if (folio_test_private(src) && - !filemap_release_folio(src, GFP_KERNEL)) + if (!filemap_release_folio(src, GFP_KERNEL)) return mode == MIGRATE_SYNC ? -EAGAIN : -EBUSY; return migrate_folio(mapping, dst, src, mode); diff --git a/mm/truncate.c b/mm/truncate.c index c0be77e5c008..0d4dd233f518 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -19,7 +19,6 @@ #include #include #include -#include /* grr. try_to_release_page */ #include #include #include "internal.h" @@ -276,7 +275,7 @@ static long mapping_evict_folio(struct address_space *mapping, if (folio_ref_count(folio) > folio_nr_pages(folio) + folio_has_private(folio) + 1) return 0; - if (folio_has_private(folio) && !filemap_release_folio(folio, 0)) + if (!filemap_release_folio(folio, 0)) return 0; return remove_mapping(mapping, folio); @@ -581,8 +580,7 @@ static int invalidate_complete_folio2(struct address_space *mapping, if (folio->mapping != mapping) return 0; - if (folio_has_private(folio) && - !filemap_release_folio(folio, GFP_KERNEL)) + if (!filemap_release_folio(folio, GFP_KERNEL)) return 0; spin_lock(&mapping->host->i_lock); diff --git a/mm/vmscan.c b/mm/vmscan.c index 04d8b88e5216..b9316f447238 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1978,7 +1978,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, * (refcount == 1) it can be freed. Otherwise, leave * the folio on the LRU so it is swappable. */ - if (folio_has_private(folio)) { + if (folio_needs_release(folio)) { if (!filemap_release_folio(folio, sc->gfp_mask)) goto activate_locked; if (!mapping && folio_ref_count(folio) == 1) { @@ -2592,9 +2592,8 @@ static void shrink_active_list(unsigned long nr_to_scan, } if (unlikely(buffer_heads_over_limit)) { - if (folio_test_private(folio) && folio_trylock(folio)) { - if (folio_test_private(folio)) - filemap_release_folio(folio, 0); + if (folio_needs_release(folio) && folio_trylock(folio)) { + filemap_release_folio(folio, 0); folio_unlock(folio); } } From patchwork Wed Nov 23 22:48:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13054436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38212C4332F for ; Wed, 23 Nov 2022 22:48:57 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CD8816B0078; Wed, 23 Nov 2022 17:48:56 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C88CC6B007B; Wed, 23 Nov 2022 17:48:56 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B50826B007D; Wed, 23 Nov 2022 17:48:56 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id A7C5C6B0078 for ; Wed, 23 Nov 2022 17:48:56 -0500 (EST) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 827C3C1276 for ; Wed, 23 Nov 2022 22:48:56 +0000 (UTC) X-FDA: 80166198672.15.1AD71F6 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf22.hostedemail.com (Postfix) with ESMTP id 1B429C000D for ; Wed, 23 Nov 2022 22:48:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669243735; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FMpD2QacSyirt4KhgIf7y2eg+2+w0SPRn1S5x80wqPI=; b=JRQP/TFEgQFU7RyZDv59Uux8pXqsyUAjbIqIB8qaaB7fBaWrhF8YnGWpysudj4YKg1lIK1 7IN3Df8T31v8y56fKffKg83YbRLwqXU1ckjjveEyIKRnpfTjfp07u8lFUxSkFVj9xdmpwl fN4uorGx9Qsq43UJbSzhZWiZWnpqRs4= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-119-ONdTnLByP52CxVtlb5LvTA-1; Wed, 23 Nov 2022 17:48:52 -0500 X-MC-Unique: ONdTnLByP52CxVtlb5LvTA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 395AD811E67; Wed, 23 Nov 2022 22:48:51 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.14]) by smtp.corp.redhat.com (Postfix) with ESMTP id E5FF24EA61; Wed, 23 Nov 2022 22:48:48 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH v4 2/3] mm, netfs, fscache: Stop read optimisation when folio removed from pagecache From: David Howells To: Linus Torvalds Cc: Rohith Surabattula , Matthew Wilcox , Matthew Wilcox , Steve French , Shyam Prasad N , Rohith Surabattula , Dave Wysochanski , Dominique Martinet , Ilya Dryomov , linux-cachefs@redhat.com, linux-cifs@vger.kernel.org, linux-afs@lists.infradead.org, v9fs-developer@lists.sourceforge.net, ceph-devel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, dhowells@redhat.com, Matthew Wilcox , Jeff Layton , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-erofs@lists.ozlabs.org, linux-cachefs@redhat.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Wed, 23 Nov 2022 22:48:46 +0000 Message-ID: <166924372614.1772793.3804564782036202222.stgit@warthog.procyon.org.uk> In-Reply-To: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> References: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> User-Agent: StGit/1.5 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 ARC-Authentication-Results: i=1; imf22.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b="JRQP/TFE"; spf=pass (imf22.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669243736; a=rsa-sha256; cv=none; b=rViYhTVHw18geQcYcjSKxeZFokXy/z1d0F0HDM6c/amBGaVG4afS2rBL98Yl4zY9hsuohm z3Klc7mt1Gj29+37K9Q4Q+MM9a1N9ktbqEeHRZbzJ8qoCEqWtpv1SLY1keJ2GIRghbm/f3 UTufhM0m1F7Kpl7ibc1+IStgfisMHYs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669243736; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=FMpD2QacSyirt4KhgIf7y2eg+2+w0SPRn1S5x80wqPI=; b=OnL8TI2P9l4NrQ/2kqUsXo/PFaKAvJAS5ZYnKnpylkib0EAqMpDv3bRtawC1hos3IXzYsh YQUyI+Dwr9HKyDMs6iv2aLtYu8nizXL41tMjmxj8En02o/mICmTk6NqbN1wKlNdSU0pX0R 3z1ATR/QsfrwCsF0q+t9O04eS3ygJUM= X-Stat-Signature: kjbh3aqizmuupdzgtsnhu119y5hdp3k8 X-Rspamd-Server: rspam08 X-Rspam-User: Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b="JRQP/TFE"; spf=pass (imf22.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com X-Rspamd-Queue-Id: 1B429C000D X-HE-Tag: 1669243735-820154 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Fscache has an optimisation by which reads from the cache are skipped until we know that (a) there's data there to be read and (b) that data isn't entirely covered by pages resident in the netfs pagecache. This is done with two flags manipulated by fscache_note_page_release(): if (... test_bit(FSCACHE_COOKIE_HAVE_DATA, &cookie->flags) && test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags)) clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); where the NO_DATA_TO_READ flag causes cachefiles_prepare_read() to indicate that netfslib should download from the server or clear the page instead. The fscache_note_page_release() function is intended to be called from ->releasepage() - but that only gets called if PG_private or PG_private_2 is set - and currently the former is at the discretion of the network filesystem and the latter is only set whilst a page is being written to the cache, so sometimes we miss clearing the optimisation. Fix this by following Willy's suggestion[1] and adding an address_space flag, AS_RELEASE_ALWAYS, that causes filemap_release_folio() to always call ->release_folio() if it's set, even if PG_private or PG_private_2 aren't set. Note that this would require folio_test_private() and page_has_private() to become more complicated. To avoid that, in the places[*] where these are used to conditionalise calls to filemap_release_folio() and try_to_release_page(), the tests are removed the those functions just jumped to unconditionally and the test is performed there. [*] There are some exceptions in vmscan.c where the check guards more than just a call to the releaser. I've added a function, folio_needs_release() to wrap all the checks for that. AS_RELEASE_ALWAYS should be set if a non-NULL cookie is obtained from fscache and cleared in ->evict_inode() before truncate_inode_pages_final() is called. Additionally, the FSCACHE_COOKIE_NO_DATA_TO_READ flag needs to be cleared and the optimisation cancelled if a cachefiles object already contains data when we open it. Changes: ======== ver #4) - Split out merging of folio_has_private()/filemap_release_folio() call pairs into a preceding patch. - Don't need to clear AS_RELEASE_ALWAYS in ->evict_inode(). ver #3) - Fixed mapping_clear_release_always() to use clear_bit() not set_bit(). - Moved a '&&' to the correct line. ver #2) - Rewrote entirely according to Willy's suggestion[1]. Reported-by: Rohith Surabattula Suggested-by: Matthew Wilcox Signed-off-by: David Howells cc: Matthew Wilcox cc: Linus Torvalds cc: Steve French cc: Shyam Prasad N cc: Rohith Surabattula cc: Dave Wysochanski cc: Dominique Martinet cc: Ilya Dryomov cc: linux-cachefs@redhat.com cc: linux-cifs@vger.kernel.org cc: linux-afs@lists.infradead.org cc: v9fs-developer@lists.sourceforge.net cc: ceph-devel@vger.kernel.org cc: linux-nfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Link: https://lore.kernel.org/r/Yk9V/03wgdYi65Lb@casper.infradead.org/ [1] Link: https://lore.kernel.org/r/164928630577.457102.8519251179327601178.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/166844174069.1124521.10890506360974169994.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/166869495238.3720468.4878151409085146764.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/1459152.1669208550@warthog.procyon.org.uk/ # v3 also --- fs/9p/cache.c | 2 ++ fs/afs/internal.h | 2 ++ fs/cachefiles/namei.c | 2 ++ fs/ceph/cache.c | 2 ++ fs/cifs/fscache.c | 2 ++ include/linux/pagemap.h | 16 ++++++++++++++++ mm/internal.h | 5 ++++- 7 files changed, 30 insertions(+), 1 deletion(-) diff --git a/fs/9p/cache.c b/fs/9p/cache.c index cebba4eaa0b5..12c0ae29f185 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c @@ -68,6 +68,8 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) &path, sizeof(path), &version, sizeof(version), i_size_read(&v9inode->netfs.inode)); + if (v9inode->netfs.cache) + mapping_set_release_always(inode->i_mapping); p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", inode, v9fs_inode_cookie(v9inode)); diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 723d162078a3..310f4111c648 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -680,6 +680,8 @@ static inline void afs_vnode_set_cache(struct afs_vnode *vnode, { #ifdef CONFIG_AFS_FSCACHE vnode->netfs.cache = cookie; + if (cookie) + mapping_set_release_always(vnode->netfs.inode.i_mapping); #endif } diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 03ca8f2f657a..50b2ee163af6 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -584,6 +584,8 @@ static bool cachefiles_open_file(struct cachefiles_object *object, if (ret < 0) goto check_failed; + clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &object->cookie->flags); + object->file = file; /* Always update the atime on an object we've just looked up (this is diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c index 177d8e8d73fe..de1dee46d3df 100644 --- a/fs/ceph/cache.c +++ b/fs/ceph/cache.c @@ -36,6 +36,8 @@ void ceph_fscache_register_inode_cookie(struct inode *inode) &ci->i_vino, sizeof(ci->i_vino), &ci->i_version, sizeof(ci->i_version), i_size_read(inode)); + if (ci->netfs.cache) + mapping_set_release_always(inode->i_mapping); } void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info *ci) diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index a1751b956318..d3f484ab1213 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -108,6 +108,8 @@ void cifs_fscache_get_inode_cookie(struct inode *inode) &cifsi->uniqueid, sizeof(cifsi->uniqueid), &cd, sizeof(cd), i_size_read(&cifsi->netfs.inode)); + if (cifsi->netfs.cache) + mapping_set_release_always(inode->i_mapping); } void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index bbccb4044222..9a824b43c6af 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -199,6 +199,7 @@ enum mapping_flags { /* writeback related tags are not used */ AS_NO_WRITEBACK_TAGS = 5, AS_LARGE_FOLIO_SUPPORT = 6, + AS_RELEASE_ALWAYS, /* Call ->release_folio(), even if no private data */ }; /** @@ -269,6 +270,21 @@ static inline int mapping_use_writeback_tags(struct address_space *mapping) return !test_bit(AS_NO_WRITEBACK_TAGS, &mapping->flags); } +static inline bool mapping_release_always(const struct address_space *mapping) +{ + return test_bit(AS_RELEASE_ALWAYS, &mapping->flags); +} + +static inline void mapping_set_release_always(struct address_space *mapping) +{ + set_bit(AS_RELEASE_ALWAYS, &mapping->flags); +} + +static inline void mapping_clear_release_always(struct address_space *mapping) +{ + clear_bit(AS_RELEASE_ALWAYS, &mapping->flags); +} + static inline gfp_t mapping_gfp_mask(struct address_space * mapping) { return mapping->gfp_mask; diff --git a/mm/internal.h b/mm/internal.h index 1fefb5181ab7..ffc5f5d3682a 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -168,7 +168,10 @@ static inline void set_page_refcounted(struct page *page) */ static inline bool folio_needs_release(struct folio *folio) { - return folio_has_private(folio); + struct address_space *mapping = folio->mapping; + + return folio_has_private(folio) || + (mapping && mapping_release_always(mapping)); } extern unsigned long highest_memmap_pfn; From patchwork Wed Nov 23 22:48:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13054437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79DD0C4332F for ; Wed, 23 Nov 2022 22:49:07 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1B44E6B007B; Wed, 23 Nov 2022 17:49:07 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 165DC6B007D; Wed, 23 Nov 2022 17:49:07 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 005AF6B007E; Wed, 23 Nov 2022 17:49:06 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id E5BE66B007B for ; Wed, 23 Nov 2022 17:49:06 -0500 (EST) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id B9C0A1A0A20 for ; Wed, 23 Nov 2022 22:49:06 +0000 (UTC) X-FDA: 80166199092.15.A27E96D Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf23.hostedemail.com (Postfix) with ESMTP id 55C4E140004 for ; Wed, 23 Nov 2022 22:49:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669243745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WHpeeqm1MJ8TYn1nRD3MVhIBofwqjS4Ni77i3McPwEA=; b=QvlLSfsA0nkcM/dVzqUYbskREDt/xnNItVXa808fHSgjRiJXxfyh6aYG18J+I6zrd4VNXf jTG8F6G0vAXX8avnPJoiygk4f9IHGN6iifP8QMWP/87NCoQLjcc4R3naIUGdu9Qxi2KGSg incoY5bRLSko1fiOVueZ5J/sjOQH24M= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-227-q0o80RfhNxCJu3990DjGhg-1; Wed, 23 Nov 2022 17:49:02 -0500 X-MC-Unique: q0o80RfhNxCJu3990DjGhg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7020D1C05AA3; Wed, 23 Nov 2022 22:49:01 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.14]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B620111E413; Wed, 23 Nov 2022 22:48:59 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH v4 3/3] mm: Make filemap_release_folio() better inform shrink_folio_list() From: David Howells To: Linus Torvalds Cc: Matthew Wilcox , Steve French , Shyam Prasad N , Rohith Surabattula , Dave Wysochanski , Dominique Martinet , Ilya Dryomov , linux-cachefs@redhat.com, linux-cifs@vger.kernel.org, linux-afs@lists.infradead.org, v9fs-developer@lists.sourceforge.net, ceph-devel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, dhowells@redhat.com, Matthew Wilcox , Jeff Layton , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-erofs@lists.ozlabs.org, linux-cachefs@redhat.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Wed, 23 Nov 2022 22:48:56 +0000 Message-ID: <166924373637.1772793.2622483388224911574.stgit@warthog.procyon.org.uk> In-Reply-To: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> References: <166924370539.1772793.13730698360771821317.stgit@warthog.procyon.org.uk> User-Agent: StGit/1.5 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669243746; a=rsa-sha256; cv=none; b=ydcan+Ml+RXahZt6CpC5Sq8bTlkJTynlDvkEalmKbC+VOpgLbA0/e6+FORWMHk6D+LdDA5 EiaUrZ079YKvwMQRWyXFvB8wNBu6MHT9bgFu9lzQWi/dyU4ddiHk3dR/36h8HhBeVvEITV mjrBc38V872TO2250TBC2+9vWy5TQQw= ARC-Authentication-Results: i=1; imf23.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=QvlLSfsA; spf=pass (imf23.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669243746; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=WHpeeqm1MJ8TYn1nRD3MVhIBofwqjS4Ni77i3McPwEA=; b=6Bnhln9xvdjjsiPuoYR1kv1dfpqUp3AR7KEoJqzY69eAxwL6pa15bkwaNKZj7hNwkQsRiS ONvlXK2fyQZsvsJCiXGzk8xKB4CBt1DLnSoKB/aKyTmzz0a2CCrPlXIC7iX5fp2WYKwmJY BbneYv/Aw1gtzaTggll414BmJVksH1Q= X-Rspam-User: X-Rspamd-Queue-Id: 55C4E140004 Authentication-Results: imf23.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=QvlLSfsA; spf=pass (imf23.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com X-Stat-Signature: 8p7t6p3drjqxump9pgsqzzkrf9yz66aj X-Rspamd-Server: rspam10 X-HE-Tag: 1669243746-260217 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Make filemap_release_folio() return one of three values: (0) FILEMAP_CANT_RELEASE_FOLIO Couldn't release the folio's private data, so the folio can't itself be released. (1) FILEMAP_RELEASED_FOLIO The private data on the folio was released and the folio can be released. (2) FILEMAP_FOLIO_HAD_NO_PRIVATE There was no private data on the folio and the folio can be released. The first must be zero so that existing tests of !filemap_release_folio() continue to work as expected; similarly the other two must both be non-zero so that existing tests of filemap_release_folio() continue to work as expected. Using this, make shrink_folio_list() choose which of three cases to follow based on the return from filemap_release_folio() rather than testing the folio's private bit itself. Signed-off-by: David Howells cc: Matthew Wilcox cc: Linus Torvalds cc: Steve French cc: Shyam Prasad N cc: Rohith Surabattula cc: Dave Wysochanski cc: Dominique Martinet cc: Ilya Dryomov cc: linux-cachefs@redhat.com cc: linux-cifs@vger.kernel.org cc: linux-afs@lists.infradead.org cc: v9fs-developer@lists.sourceforge.net cc: ceph-devel@vger.kernel.org cc: linux-nfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Link: https://lore.kernel.org/r/1459152.1669208550@warthog.procyon.org.uk/ # v3 --- include/linux/pagemap.h | 7 ++++++- mm/filemap.c | 20 ++++++++++++++------ mm/vmscan.c | 29 +++++++++++++++-------------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 9a824b43c6af..b763182b6d3f 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1124,7 +1124,12 @@ void replace_page_cache_page(struct page *old, struct page *new); void delete_from_page_cache_batch(struct address_space *mapping, struct folio_batch *fbatch); int try_to_release_page(struct page *page, gfp_t gfp); -bool filemap_release_folio(struct folio *folio, gfp_t gfp); +enum filemap_released_folio { + FILEMAP_CANT_RELEASE_FOLIO = 0, /* (This must be 0) Release failed */ + FILEMAP_RELEASED_FOLIO = 1, /* Folio's private data released */ + FILEMAP_FOLIO_HAD_NO_PRIVATE = 2, /* Folio had no private data */ +}; +enum filemap_released_folio filemap_release_folio(struct folio *folio, gfp_t gfp); loff_t mapping_seek_hole_data(struct address_space *, loff_t start, loff_t end, int whence); diff --git a/mm/filemap.c b/mm/filemap.c index 93757247cd11..859831c70439 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3934,20 +3934,28 @@ EXPORT_SYMBOL(generic_file_write_iter); * this page (__GFP_IO), and whether the call may block * (__GFP_RECLAIM & __GFP_FS). * - * Return: %true if the release was successful, otherwise %false. + * Return: %FILEMAP_RELEASED_FOLIO if the release was successful, + * %FILEMAP_CANT_RELEASE_FOLIO if the private data couldn't be released and + * %FILEMAP_FOLIO_HAD_NO_PRIVATE if there was no private data. */ -bool filemap_release_folio(struct folio *folio, gfp_t gfp) +enum filemap_released_folio filemap_release_folio(struct folio *folio, + gfp_t gfp) { struct address_space * const mapping = folio->mapping; + bool released; BUG_ON(!folio_test_locked(folio)); if (!folio_needs_release(folio)) - return true; + return FILEMAP_FOLIO_HAD_NO_PRIVATE; if (folio_test_writeback(folio)) - return false; + return FILEMAP_CANT_RELEASE_FOLIO; if (mapping && mapping->a_ops->release_folio) - return mapping->a_ops->release_folio(folio, gfp); - return try_to_free_buffers(folio); + released = mapping->a_ops->release_folio(folio, gfp); + else + released = try_to_free_buffers(folio); + + return released ? + FILEMAP_RELEASED_FOLIO : FILEMAP_CANT_RELEASE_FOLIO; } EXPORT_SYMBOL(filemap_release_folio); diff --git a/mm/vmscan.c b/mm/vmscan.c index b9316f447238..d5c7b3be9947 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1978,25 +1978,26 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, * (refcount == 1) it can be freed. Otherwise, leave * the folio on the LRU so it is swappable. */ - if (folio_needs_release(folio)) { - if (!filemap_release_folio(folio, sc->gfp_mask)) - goto activate_locked; + switch (filemap_release_folio(folio, sc->gfp_mask)) { + case FILEMAP_CANT_RELEASE_FOLIO: + goto activate_locked; + case FILEMAP_RELEASED_FOLIO: if (!mapping && folio_ref_count(folio) == 1) { folio_unlock(folio); if (folio_put_testzero(folio)) goto free_it; - else { - /* - * rare race with speculative reference. - * the speculative reference will free - * this folio shortly, so we may - * increment nr_reclaimed here (and - * leave it off the LRU). - */ - nr_reclaimed += nr_pages; - continue; - } + /* + * rare race with speculative reference. the + * speculative reference will free this folio + * shortly, so we may increment nr_reclaimed + * here (and leave it off the LRU). + */ + nr_reclaimed += nr_pages; + continue; } + break; + case FILEMAP_FOLIO_HAD_NO_PRIVATE: + break; } if (folio_test_anon(folio) && !folio_test_swapbacked(folio)) {