From: Pedro Falcato <pfalcato@suse.de>
To: Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>
Cc: Pedro Falcato <pfalcato@suse.de>, Zi Yan <ziy@nvidia.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
"Liam R. Howlett" <liam@infradead.org>,
Nico Pache <npache@redhat.com>,
Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
Usama Arif <usama.arif@linux.dev>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/8] mm/khugepaged: factor out page cache folio reading
Date: Mon, 20 Jul 2026 15:29:07 +0100 [thread overview]
Message-ID: <20260720142913.846902-3-pfalcato@suse.de> (raw)
In-Reply-To: <20260720142913.846902-1-pfalcato@suse.de>
The two mechanisms (shmem, filemap) are quite similar and only change in
subtleties. There is no need to have two variants. Factor this out into
its own separate function, shared by both paths.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
mm/khugepaged.c | 67 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 44 insertions(+), 23 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index d4de507ac001..4cc6917a55c7 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2230,42 +2230,63 @@ struct collapse_file_state {
unsigned int is_shmem : 1;
};
+static struct folio *collapse_read_folio(pgoff_t index, struct collapse_file_state *state)
+{
+ const bool may_bring_uptodate = state->is_shmem;
+ struct folio *folio = state->folio;
+
+ if (!folio || xa_is_value(folio) ||
+ (may_bring_uptodate && !folio_test_uptodate(folio))) {
+ xas_unlock_irq(state->xas);
+ if (state->is_shmem) {
+ /* swap in or instantiate fallocated page */
+ if (shmem_get_folio(state->mapping->host, index, 0,
+ &folio, SGP_NOALLOC))
+ return NULL;
+ } else {
+ page_cache_sync_readahead(state->mapping, &state->file->f_ra,
+ state->file, index,
+ state->end - index);
+ folio = filemap_lock_folio(state->mapping, index);
+ if (IS_ERR(folio))
+ return NULL;
+ }
+ }
+
+ return folio;
+}
+
static enum scan_result prepare_collapse_file_folio(pgoff_t index, struct collapse_file_state *state)
{
struct address_space *mapping = state->mapping;
enum scan_result result = SCAN_SUCCEED;
const int is_shmem = state->is_shmem;
- struct folio *folio = state->folio;
+ struct folio *folio;
+
+ folio = collapse_read_folio(index, state);
+ if (!folio)
+ return SCAN_FAIL;
+ if (folio != state->folio) {
+ /*
+ * collapse_read_folio() got a new folio. This folio is locked
+ * and ref'd up. Nothing tricky (dirty, writeback, etc) can
+ * happen, so bail now. But before that, drain the local LRU
+ * add batch. Otherwise, it's very possible folio_isolate_lru()
+ * will not succeed.
+ */
+ lru_add_drain();
+ goto xa_unlocked;
+ }
if (is_shmem) {
- if (xa_is_value(folio) || !folio_test_uptodate(folio)) {
- xas_unlock_irq(state->xas);
- /* swap in or instantiate fallocated page */
- if (shmem_get_folio(mapping->host, index, 0,
- &folio, SGP_NOALLOC))
- result = SCAN_FAIL;
- /* drain lru cache to help folio_isolate_lru() */
- lru_add_drain();
- goto xa_unlocked;
- } else if (folio_trylock(folio)) {
+ if (folio_trylock(folio)) {
folio_get(folio);
} else {
result = SCAN_PAGE_LOCK;
goto xa_locked;
}
} else { /* !is_shmem */
- if (!folio || xa_is_value(folio)) {
- xas_unlock_irq(state->xas);
- page_cache_sync_readahead(mapping, &state->file->f_ra,
- state->file, index,
- state->end - index);
- /* drain lru cache to help folio_isolate_lru() */
- lru_add_drain();
- folio = filemap_lock_folio(mapping, index);
- if (IS_ERR(folio))
- result = SCAN_FAIL;
- goto xa_unlocked;
- } else if (folio_test_dirty(folio)) {
+ if (folio_test_dirty(folio)) {
/*
* This page is dirty because it hasn't
* been flushed since first write.
--
2.55.0
next prev parent reply other threads:[~2026-07-20 14:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 14:29 [PATCH 0/8] mm/khugepaged: collapse_file() cleanups Pedro Falcato
2026-07-20 14:29 ` [PATCH 1/8] mm/khugepaged: separate out windy folio logic from collapse_file Pedro Falcato
2026-07-20 15:38 ` Lorenzo Stoakes (ARM)
2026-07-20 15:39 ` Lorenzo Stoakes (ARM)
2026-07-20 14:29 ` Pedro Falcato [this message]
2026-07-20 16:53 ` [PATCH 2/8] mm/khugepaged: factor out page cache folio reading Lorenzo Stoakes (ARM)
2026-07-20 14:29 ` [PATCH 3/8] mm/khugepaged: factor out and simplify dirty/writeback handling Pedro Falcato
2026-07-20 14:29 ` [PATCH 4/8] mm/khugepaged: simplify prepare folio locking and exit paths Pedro Falcato
2026-07-20 14:29 ` [PATCH 5/8] mm/khugepaged: add kerneldoc to prepare_collapse_file_folio() Pedro Falcato
2026-07-20 14:29 ` [PATCH 6/8] mm/khugepaged: hoist isolation into collapse_isolate_folio() Pedro Falcato
2026-07-20 14:29 ` [PATCH 7/8] mm/khugepaged: hoist more code " Pedro Falcato
2026-07-20 14:29 ` [PATCH 8/8] mm/khugepaged: fix and flesh out try_to_unmap_flush() comment Pedro Falcato
2026-07-20 15:21 ` [PATCH 0/8] mm/khugepaged: collapse_file() cleanups Nico Pache
2026-07-20 19:49 ` Pedro Falcato
2026-07-20 20:14 ` Nico Pache
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=20260720142913.846902-3-pfalcato@suse.de \
--to=pfalcato@suse.de \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=npache@redhat.com \
--cc=ryan.roberts@arm.com \
--cc=usama.arif@linux.dev \
--cc=ziy@nvidia.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