Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
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
>
>



  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