From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: linux-mm@kvack.org
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Hugh Dickins <hughd@google.com>,
William Kucharski <william.kucharski@oracle.com>,
Jani Nikula <jani.nikula@linux.intel.com>,
Alexey Dobriyan <adobriyan@gmail.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Chris Wilson <chris@chris-wilson.co.uk>,
Matthew Auld <matthew.auld@intel.com>,
Huang Ying <ying.huang@intel.com>,
intel-gfx@lists.freedesktop.org, cgroups@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 8/8] mm: Add find_lock_head
Date: Thu, 10 Sep 2020 19:33:18 +0100 [thread overview]
Message-ID: <20200910183318.20139-9-willy@infradead.org> (raw)
In-Reply-To: <20200910183318.20139-1-willy@infradead.org>
Add a new FGP_HEAD flag which avoids calling find_subpage() and add a
convenience wrapper for it.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
include/linux/pagemap.h | 32 ++++++++++++++++++++++++++------
mm/filemap.c | 9 ++++++---
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index f374618b2c93..4e52a3ff92fb 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -278,6 +278,7 @@ pgoff_t page_cache_prev_miss(struct address_space *mapping,
#define FGP_NOFS 0x00000010
#define FGP_NOWAIT 0x00000020
#define FGP_FOR_MMAP 0x00000040
+#define FGP_HEAD 0x00000080
struct page *pagecache_get_page(struct address_space *mapping, pgoff_t offset,
int fgp_flags, gfp_t cache_gfp_mask);
@@ -309,18 +310,37 @@ static inline struct page *find_get_page_flags(struct address_space *mapping,
* @mapping: the address_space to search
* @offset: the page index
*
- * Looks up the page cache slot at @mapping & @offset. If there is a
+ * Looks up the page cache entry at @mapping & @offset. If there is a
* page cache page, it is returned locked and with an increased
* refcount.
*
- * Otherwise, %NULL is returned.
- *
- * find_lock_page() may sleep.
+ * Context: May sleep.
+ * Return: A struct page or %NULL if there is no page in the cache for this
+ * index.
*/
static inline struct page *find_lock_page(struct address_space *mapping,
- pgoff_t offset)
+ pgoff_t index)
+{
+ return pagecache_get_page(mapping, index, FGP_LOCK, 0);
+}
+
+/**
+ * find_lock_head - Locate, pin and lock a pagecache page.
+ * @mapping: The address_space to search.
+ * @offset: The page index.
+ *
+ * Looks up the page cache entry at @mapping & @offset. If there is a
+ * page cache page, its head page is returned locked and with an increased
+ * refcount.
+ *
+ * Context: May sleep.
+ * Return: A struct page which is !PageTail, or %NULL if there is no page
+ * in the cache for this index.
+ */
+static inline struct page *find_lock_head(struct address_space *mapping,
+ pgoff_t index)
{
- return pagecache_get_page(mapping, offset, FGP_LOCK, 0);
+ return pagecache_get_page(mapping, index, FGP_LOCK | FGP_HEAD, 0);
}
/**
diff --git a/mm/filemap.c b/mm/filemap.c
index 453535170b8d..e429e02317ef 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1659,6 +1659,8 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t index)
*
* * %FGP_ACCESSED - The page will be marked accessed.
* * %FGP_LOCK - The page is returned locked.
+ * * %FGP_HEAD - If the page is present and a THP, return the head page
+ * rather than the exact page specified by the index.
* * %FGP_CREAT - If no page is present then a new page is allocated using
* @gfp_mask and added to the page cache and the VM's LRU list.
* The page is returned locked and with an increased refcount.
@@ -1687,7 +1689,6 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
page = NULL;
if (!page)
goto no_page;
- page = find_subpage(page, index);
if (fgp_flags & FGP_LOCK) {
if (fgp_flags & FGP_NOWAIT) {
@@ -1700,12 +1701,12 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
}
/* Has the page been truncated? */
- if (unlikely(compound_head(page)->mapping != mapping)) {
+ if (unlikely(page->mapping != mapping)) {
unlock_page(page);
put_page(page);
goto repeat;
}
- VM_BUG_ON_PAGE(page->index != index, page);
+ VM_BUG_ON_PAGE(!thp_contains(page, index), page);
}
if (fgp_flags & FGP_ACCESSED)
@@ -1715,6 +1716,8 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
if (page_is_idle(page))
clear_page_idle(page);
}
+ if (!(fgp_flags & FGP_HEAD))
+ page = find_subpage(page, index);
no_page:
if (!page && (fgp_flags & FGP_CREAT)) {
--
2.28.0
next prev parent reply other threads:[~2020-09-10 18:33 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-10 18:33 [PATCH v2 0/8] Return head pages from find_*_entry Matthew Wilcox (Oracle)
2020-09-10 18:33 ` [PATCH v2 1/8] mm: Factor find_get_incore_page out of mincore_page Matthew Wilcox (Oracle)
2020-09-10 18:33 ` [PATCH v2 2/8] mm: Use find_get_incore_page in memcontrol Matthew Wilcox (Oracle)
2020-09-10 18:33 ` [PATCH v2 3/8] mm: Optimise madvise WILLNEED Matthew Wilcox (Oracle)
2020-09-14 16:17 ` Qian Cai
2020-09-14 16:47 ` Qian Cai
2020-09-14 16:50 ` Matthew Wilcox
2020-09-14 19:44 ` Qian Cai
2020-09-10 18:33 ` [PATCH v2 4/8] proc: Optimise smaps for shmem entries Matthew Wilcox (Oracle)
2020-09-10 18:33 ` [PATCH v2 5/8] i915: Use find_lock_page instead of find_lock_entry Matthew Wilcox (Oracle)
2020-09-10 18:33 ` [PATCH v2 6/8] mm: Convert find_get_entry to return the head page Matthew Wilcox (Oracle)
2020-09-14 8:55 ` [mm] 2037ab69a5: BUG:KASAN:null-ptr-deref_in_t kernel test robot
2020-09-14 11:27 ` Matthew Wilcox
2020-09-10 18:33 ` [PATCH v2 7/8] mm/shmem: Return head page from find_lock_entry Matthew Wilcox (Oracle)
2020-09-12 3:20 ` Matthew Wilcox
2020-09-10 18:33 ` Matthew Wilcox (Oracle) [this message]
2020-09-15 8:10 ` [PATCH v2 0/8] Return head pages from find_*_entry Hugh Dickins
2020-09-15 12:53 ` Naresh Kamboju
2020-09-15 13:08 ` Matthew Wilcox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200910183318.20139-9-willy@infradead.org \
--to=willy@infradead.org \
--cc=adobriyan@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=cgroups@vger.kernel.org \
--cc=chris@chris-wilson.co.uk \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew.auld@intel.com \
--cc=william.kucharski@oracle.com \
--cc=ying.huang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).