From: Joanne Koong <joannelkoong@gmail.com>
To: akpm@linux-foundation.org, david@kernel.org, ljs@kernel.org
Cc: usama.arif@linux.dev, hannes@cmpxchg.org, baohua@kernel.org,
alex@ghiti.fr, ziy@nvidia.com, baolin.wang@linux.alibaba.com,
liam@infradead.org, npache@redhat.com, ryan.roberts@arm.com,
dev.jain@arm.com, lance.yang@linux.dev, vbabka@kernel.org,
rppt@kernel.org, surenb@google.com, mhocko@suse.com,
willy@infradead.org, linux-mm@kvack.org
Subject: [PATCH v2 1/3] mm/huge_memory: make thp_underused() work for mTHP folios
Date: Wed, 16 Sep 2026 15:44:35 -0700 [thread overview]
Message-ID: <20260916224437.1164512-2-joannelkoong@gmail.com> (raw)
In-Reply-To: <20260916224437.1164512-1-joannelkoong@gmail.com>
thp_underused() decides whether a large folio on the deferred split list
is underused and should be split so that its zero-filled subpages can be
reclaimed.
Today it only ever checks if the folio is underused on PMD-sized folios.
As such, thp_underused() assumes throughout that the folio has
HPAGE_PMD_NR pages. A later patch will be queueing anonymous mTHP folios
on the deferred split list as well, at which point this assumption will
not be correct anymore.
Generalize thp_underused() to be folio-size-aware instead of hardcoded
to PMD-sized folios. The check for whether a folio can ever be underused
is moved into its own function, thp_can_be_underused(), as this will get
reused in the next patch when determining if the folio should get added
to the deferred split queue.
khugepaged_max_ptes_none keeps its meaning as an absolute number of
pages, which is also how khugepaged applies it when collapsing to PMD
order. It is deliberately not scaled down per folio order (collapse
rejected proportional scaling of intermediate values because it either
lets the memory footprint creep or ends up confusing to reason about).
Read as an absolute count, this knob gains a useful second meaning for
mTHP as being the smallest folio size that takes part in underused
splitting at all.
There is no functional change, as for a PMD-sized folio nr_pages is
HPAGE_PMD_NR.
Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
mm/huge_memory.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 1e5d68acf62a..c6ca2a541128 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4541,6 +4541,23 @@ bool __folio_unqueue_deferred_split(struct folio *folio)
return unqueued; /* useful for debug warnings */
}
+static bool thp_can_be_underused(unsigned long nr_pages,
+ unsigned long max_ptes_none)
+{
+ /*
+ * The sysctl maximum means the user tolerates any number of zero-filled
+ * pages, so nothing is ever underused.
+ */
+ if (max_ptes_none == HPAGE_PMD_NR - 1)
+ return false;
+
+ /*
+ * A folio no larger than the number of zero-filled pages the user
+ * tolerates can never exceed it. It can never be underused.
+ */
+ return nr_pages > max_ptes_none;
+}
+
/* partially_mapped=false won't clear PG_partially_mapped folio flag */
void deferred_split_folio(struct folio *folio, bool partially_mapped)
{
@@ -4602,25 +4619,27 @@ static unsigned long deferred_split_count(struct shrinker *shrink,
static bool thp_underused(struct folio *folio)
{
- int num_zero_pages = 0, num_filled_pages = 0;
- int i;
+ const unsigned long max_ptes_none = khugepaged_max_ptes_none;
+ const unsigned long nr_pages = folio_nr_pages(folio);
+ unsigned long num_zero_pages = 0, num_filled_pages = 0;
+ unsigned long i;
- if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1)
+ if (!thp_can_be_underused(nr_pages, max_ptes_none))
return false;
if (folio_contain_hwpoisoned_page(folio))
return false;
- for (i = 0; i < folio_nr_pages(folio); i++) {
+ for (i = 0; i < nr_pages; i++) {
if (pages_identical(folio_page(folio, i), ZERO_PAGE(0))) {
- if (++num_zero_pages > khugepaged_max_ptes_none)
+ if (++num_zero_pages > max_ptes_none)
return true;
} else {
/*
* Another path for early exit once the number
* of non-zero filled pages exceeds threshold.
*/
- if (++num_filled_pages >= HPAGE_PMD_NR - khugepaged_max_ptes_none)
+ if (++num_filled_pages >= nr_pages - max_ptes_none)
return false;
}
}
--
2.52.0
next prev parent reply other threads:[~2026-09-16 22:48 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 22:44 [PATCH v2 0/3] mm: split underused anonymous mTHP folios Joanne Koong
2026-09-16 22:44 ` Joanne Koong [this message]
2026-09-16 22:44 ` [PATCH v2 2/3] mm/huge_memory: don't queue folios that can never be underused Joanne Koong
2026-09-16 22:44 ` [PATCH v2 3/3] mm/memory: add anonymous mTHP folios to the deferred split list Joanne Koong
2026-09-20 16:20 ` [PATCH v2 0/3] mm: split underused anonymous mTHP folios Lance Yang
2026-09-21 10:04 ` Barry Song
2026-09-21 10:08 ` Usama Arif
2026-09-21 10:22 ` David Hildenbrand (Arm)
2026-09-22 10:33 ` Kiryl Shutsemau
2026-09-21 10:12 ` David Hildenbrand (Arm)
2026-09-23 0:44 ` Joanne Koong
2026-09-23 6:00 ` Barry Song
2026-09-25 22:40 ` Joanne Koong
2026-09-23 9:44 ` David Hildenbrand (Arm)
2026-09-25 23:47 ` Joanne Koong
2026-09-28 8:03 ` Barry Song
2026-10-01 9:10 ` Joanne Koong
2026-09-28 19:20 ` David Hildenbrand (Arm)
2026-10-01 9:59 ` Joanne Koong
2026-09-21 10:23 ` David Hildenbrand (Arm)
2026-09-21 20:33 ` Joanne Koong
2026-09-22 18:59 ` David Hildenbrand (Arm)
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=20260916224437.1164512-2-joannelkoong@gmail.com \
--to=joannelkoong@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=npache@redhat.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--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