From: Xueyuan Chen <xueyuan.chen21@gmail.com>
To: zhangbo0325@gmail.com
Cc: akpm@linux-foundation.org, vbabka@kernel.org, david@kernel.org,
surenb@google.com, mhocko@suse.com, brendan.jackman@linux.dev,
hannes@cmpxchg.org, ziy@nvidia.com, ljs@kernel.org,
liam@infradead.org, rppt@kernel.org, qi.zheng@linux.dev,
shakeel.butt@linux.dev, kasong@tencent.com, baohua@kernel.org,
axelrasmussen@google.com, yuanchu@google.com, weixugc@google.com,
zhaonanzhe@xiaomi.com, lipengfei28@xiaomi.com,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
zhangbo56@xiaomi.com
Subject: Re: [RFC PATCH 4/4] mm: adjust free_pages to make __zone_watermark_ok() mTHP-aware
Date: Thu, 3 Sep 2026 10:46:03 +0800 [thread overview]
Message-ID: <20260903024629.574484-1-xueyuan.chen21@gmail.com> (raw)
In-Reply-To: <20260825043833.2659350-5-zhangbo56@xiaomi.com>
On Tue, Aug 25, 2026 at 12:38:33PM +0800, Bo Zhang wrote:
>To improve the mTHP allocation success rate and reduce
>fragmentation over time, introduce
>zone_effective_free_pages() for mTHP-aware free page accounting.
>
>Refactor the free page counting logic used by pgdat_balanced() and
>compaction_suit_allocation_order() into a shared helper function
>zone_effective_free_pages().
>
>The function selects the appropriate free page metric based on context:
>- defrag_mode: use NR_FREE_PAGES_BLOCKS (whole pageblock accounting)
>- mTHP always-enabled: count only free pages in buddy blocks >= the
> minimum always-enabled mTHP order, since smaller fragments cannot
> satisfy mTHP allocations
>- otherwise: use NR_FREE_PAGES
>
>Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
>---
> mm/compaction.c | 38 ++++++++++++++++++++++++++++++++++----
> mm/internal.h | 3 +++
> mm/vmscan.c | 23 +++++------------------
> 3 files changed, 42 insertions(+), 22 deletions(-)
>
>diff --git a/mm/compaction.c b/mm/compaction.c
>index 15b92475562a..29be72597415 100644
>--- a/mm/compaction.c
>+++ b/mm/compaction.c
>@@ -2528,6 +2528,38 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
> return false;
> }
>
>+/**
>+ * zone_effective_free_pages - get free pages relevant to allocation order
>+ * @zone: target zone
>+ * @order: allocation order
>+ * @use_blocks: if true, use NR_FREE_PAGES_BLOCKS
>+ *
>+ * In defrag_mode, watermarks must be met in whole blocks to avoid
>+ * polluting allocator fallbacks. kswapd usually cannot accomplish
>+ * this on its own and needs kcompactd support.
>+ *
>+ * When mTHP always-enabled orders are configured, count only free pages
>+ * in blocks >= min mTHP order, as smaller fragments cannot satisfy mTHP
>+ * allocations.
>+ */
>+unsigned long zone_effective_free_pages(struct zone *zone,
>+ unsigned int order,
>+ bool use_blocks)
>+{
>+ if (use_blocks)
>+ return zone_page_state(zone, NR_FREE_PAGES_BLOCKS);
>+
>+ if (READ_ONCE(huge_anon_orders_always) && order == compact_hpage_order()) {
>+ unsigned long free_pages = 0;
>+
>+ for (int o = order; o < NR_PAGE_ORDERS; o++)
>+ free_pages += zone->free_area[o].nr_free << o;
>+ return free_pages;
>+ }
>+
>+ return zone_page_state(zone, NR_FREE_PAGES);
>+}
>+
> /*
> * Should we do compaction for target allocation order.
> * Return COMPACT_SUCCESS if allocation for target order can be already
>@@ -2543,10 +2575,8 @@ compaction_suit_allocation_order(struct zone *zone, unsigned int order,
> unsigned long free_pages;
> unsigned long watermark;
>
>- if (kcompactd && defrag_mode)
>- free_pages = zone_page_state(zone, NR_FREE_PAGES_BLOCKS);
>- else
>- free_pages = zone_page_state(zone, NR_FREE_PAGES);
>+ free_pages = zone_effective_free_pages(zone, order,
>+ kcompactd && defrag_mode);
>
> watermark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK);
> if (__zone_watermark_ok(zone, order, watermark, highest_zoneidx,
>diff --git a/mm/internal.h b/mm/internal.h
>index 38b1165212c9..14bb9543879b 100644
>--- a/mm/internal.h
>+++ b/mm/internal.h
>@@ -1654,4 +1654,7 @@ static inline bool can_spin_trylock(void)
> return true;
> }
>
>+unsigned long zone_effective_free_pages(struct zone *zone,
>+ unsigned int order,
>+ bool use_blocks);
> #endif /* __MM_INTERNAL_H */
>diff --git a/mm/vmscan.c b/mm/vmscan.c
>index c1404a59523d..a419a2c2fca4 100644
>--- a/mm/vmscan.c
>+++ b/mm/vmscan.c
>@@ -6966,7 +6966,6 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int highest_zoneidx)
> * meet watermarks.
> */
> for_each_managed_zone_pgdat(zone, pgdat, i, highest_zoneidx) {
>- enum zone_stat_item item;
> unsigned long free_pages;
>
> if (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING)
>@@ -6974,21 +6973,6 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int highest_zoneidx)
> else
> mark = high_wmark_pages(zone);
>
>- /*
>- * In defrag_mode, watermarks must be met in whole
>- * blocks to avoid polluting allocator fallbacks.
>- *
>- * However, kswapd usually cannot accomplish this on
>- * its own and needs kcompactd support. Once it's
>- * reclaimed a compaction gap, and kswapd_shrink_node
>- * has dropped order, simply ensure there are enough
>- * base pages for compaction, wake kcompactd & sleep.
>- */
>- if (defrag_mode && order)
>- item = NR_FREE_PAGES_BLOCKS;
>- else
>- item = NR_FREE_PAGES;
>-
> /*
> * When there is a high number of CPUs in the system,
> * the cumulative error from the vmstat per-cpu cache
>@@ -7001,9 +6985,12 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int highest_zoneidx)
> * counter won't actually be per-cpu cached. But keep
> * things simple for now; revisit when somebody cares.
> */
>- free_pages = zone_page_state(zone, item);
>+ free_pages = zone_effective_free_pages(zone, order,
>+ defrag_mode & order);
Hi Bo,
zone_effective_free_pages(zone, order, defrag_mode & order);
"&" should be "&&". defrag_mode is 0 or 1, so this is just order & 1:
works for order-3 by accident, always 0 for order-2.
Same for the zone_page_state_snapshot() call below.
Thanks,
Xueyuan
> if (zone->percpu_drift_mark && free_pages < zone->percpu_drift_mark)
>- free_pages = zone_page_state_snapshot(zone, item);
>+ free_pages = zone_page_state_snapshot(zone,
>+ defrag_mode & order ?
>+ NR_FREE_PAGES_BLOCKS : NR_FREE_PAGES);
>
> if (__zone_watermark_ok(zone, order, mark, highest_zoneidx,
> 0, free_pages))
>--
>2.34.1
>
>
next prev parent reply other threads:[~2026-09-03 2:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-25 4:38 [RFC PATCH 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
2026-08-25 4:38 ` [RFC PATCH 1/4] mm: compaction: make proactive compaction mTHP-aware Bo Zhang
2026-09-03 14:11 ` Bo Zhang
2026-08-25 4:38 ` [RFC PATCH 2/4] mm: compaction: skip isolating large folios that satisfy the mTHP order Bo Zhang
2026-09-03 14:29 ` Bo Zhang
2026-08-25 4:38 ` [RFC PATCH 3/4] mm: compaction: don't skip proactive compaction for non-costly mTHP Bo Zhang
2026-09-03 14:32 ` Bo Zhang
2026-08-25 4:38 ` [RFC PATCH 4/4] mm: adjust free_pages to make __zone_watermark_ok() mTHP-aware Bo Zhang
2026-09-03 2:46 ` Xueyuan Chen [this message]
2026-09-03 13:56 ` Bo Zhang
2026-09-03 15:09 ` Bo Zhang
2026-09-07 2:51 ` [RFC PATCH 0/4] mm: compaction: mTHP-friendly memory compaction Zi Yan
2026-09-07 8:45 ` Bo Zhang
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=20260903024629.574484-1-xueyuan.chen21@gmail.com \
--to=xueyuan.chen21@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=brendan.jackman@linux.dev \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lipengfei28@xiaomi.com \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=qi.zheng@linux.dev \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=weixugc@google.com \
--cc=yuanchu@google.com \
--cc=zhangbo0325@gmail.com \
--cc=zhangbo56@xiaomi.com \
--cc=zhaonanzhe@xiaomi.com \
--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