* [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
@ 2026-10-01 0:14 Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 1/4] mm: compaction: parameterize fragmentation score by order Bo Zhang
` (5 more replies)
0 siblings, 6 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-01 0:14 UTC (permalink / raw)
To: akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
Hi all,
This series improves memory compaction to better serve mTHP (multi-size
THP) allocations, particularly for small orders like order-2 (16KB).
The changes focus on the proactive (kcompactd) compaction path.
Problem:
The current proactive compaction targets COMPACTION_HPAGE_ORDER (order-9,
2MB), which is unfriendly to mTHP in two ways:
1. It migrates folios that already satisfy mTHP allocation needs. For
example, an order-2 folio is a valid mTHP page, yet compaction still
moves it around trying to form order-9 blocks. This is unnecessary
work and wastes energy.
2. Compaction designed for 2MB huge pages is too heavyweight for mTHP.
mTHP allocations are frequent and only require small contiguous blocks
(e.g., 4 pages for order-2). A lighter-weight, mTHP-aware compaction
strategy is needed to reduce overhead and power consumption.
Approach:
This series makes four changes:
1. Generalize the fragmentation score functions to accept an order
parameter. This is a pure refactor with no functional change; all
callers still pass COMPACTION_HPAGE_ORDER.
2. Use the highest always-enabled mTHP order as the proactive compaction
target. Because a fragmentation score for a small order is naturally
much lower than for order-9 under the same fragmentation state, the
proactive watermark is scaled down in proportion to the target order;
otherwise a small order would almost never reach the trigger threshold.
3. During proactive compaction (compact_memory), skip isolating folios
that already satisfy mTHP requirements, avoiding unnecessary migration
overhead.
4. For non-costly mTHP orders, restrict proactive compaction to movable
(and CMA) pageblocks. Unmovable/reclaimable blocks are dominated by
non-migratable kernel allocations. scanning them wastes cycles because
a small order can be satisfied from movable blocks alone. Costly orders
keep scanning all blocks, since they are harder to form and benefit
from any migratable page available.
Test setup:
x86 host, arm64 cross-build (defconfig + CONFIG_DEBUG_INFO=y,
CONFIG_DEBUG_INFO_DWARF5=y), booted with mem=4G. order-3 (32KB) mTHP is
set to "always"; ext4 root mounted data=journal. The kernel build
naturally fragments order-3 free memory during the run.
Runtime (two defrag modes were tested, see Results):
echo always > .../hugepages-32kB/enabled
echo madvise > .../transparent_hugepage/defrag # or: always
echo 20 > /proc/sys/vm/compaction_proactiveness
A background loop keeps proactiveness poked every 100ms so kcompactd
re-evaluates promptly (its default 500ms interval is too coarse to catch
the transient order-3 fragmentation peaks under this workload):
while true; do
echo 20 > /proc/sys/vm/compaction_proactiveness
sleep 0.1
done
Workload: make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- vmlinux -j28
5 rounds per configuration; each round: make clean + drop_caches, then
counter deltas around the build. The baseline is the unmodified kernel.
Results (5-round means). anon_fault_alloc is within 1% between kernels,
so the fallback numbers are directly comparable.
defrag=madvise:
w/o patch w/ patch change
-------------------------- ----------- ----------- --------
anon_fault_alloc 14,307,597 14,401,699 +1%
anon_fault_fallback 97,701 40,975 -58%
fallback ratio 0.68% 0.28%
compact_isolated 8,479,773 1,458,949 -83%
compact_migrate_scanned 78,198,828 22,900,359 -71%
kcompactd cpu (s) 43 7 -84%
sys (kernel build) 6m34s 6m34s ~0%
defrag=always:
w/o patch w/ patch change
-------------------------- ----------- ----------- --------
anon_fault_alloc 14,370,984 14,404,234 ~0%
anon_fault_fallback 619 823
compact_stall 979 585 -40%
compact_isolated 6,390,940 2,431,800 -62%
compact_migrate_scanned 86,171,095 46,339,911 -46%
kcompactd cpu (s) 36 13 -62%
sys (kernel build) 6m34s 6m27s -1.8%
1. With defrag=madvise, the patch cuts mTHP fallback by 58% (ratio
0.68% -> 0.28%).
2. With defrag=always, direct compaction already keeps fallback near
zero, and the patch instead cuts direct compaction stalls by 40%.
In both cases the compaction is done far more cheaply (kcompactd CPU
-62..84%, compact_isolated/scanned -46..83%).
Open questions:
1. In skip_isolation_on_order() and elsewhere, the target order is read
from huge_anon_orders_always directly, since during proactive
compaction cc->order is -1 (via compact_memory) and there is no clean
way to plumb the mTHP order down. This variable can change under
userspace at any time, making the semantics fragile. Ideas on how to
pass the target order through the proactive path cleanly are welcome.
2. The proactive watermark is scaled linearly by the target order
(wmark * order / COMPACTION_HPAGE_ORDER). This is empirical; a more
principled cross-order normalization of the fragmentation score would
be welcome.
Changes since v1
================
The series is now scoped to the proactive compaction path only. Two
patches from v1 were dropped, and two new mechanisms were added:
- Dropped v1 patch 3 ("don't skip proactive compaction for non-costly
mTHP", i.e. running proactive compaction concurrently with kswapd).
Follow-up testing showed it lowered fallback mainly by driving extra
anonymous reclaim/swap rather than by better compaction; keeping the
original kswapd back-off avoids trading workingset for mTHP fallback.
- Dropped v1 patch 4 (mTHP-aware zone_effective_free_pages() watermark):
it added reclaim pressure without a clear net benefit in this scope.
- Split the former patch 1 into a pure refactor (parameterize the
fragmentation score by order) plus the mTHP-targeting change, so the
mechanical and behavioural parts can be reviewed independently.
- Added the proactive watermark scaling by target order, so a small mTHP
order can actually reach the trigger threshold.
- Added patch 4 (skip unmovable blocks for non-costly proactive mTHP
compaction). Without it, proactive compaction wastes most of its
scanning on unmovable blocks full of kernel allocations; with it,
kcompactd's CPU and the scanned/isolated counters drop by an order of
magnitude while fallback still improves.
- compact_hpage_order() uses __fls() (highest always-enabled mTHP order)
guarded by #ifdef CONFIG_TRANSPARENT_HUGEPAGE (m68k allmodconfig build
fix from the kernel test robot).
- Refreshed test data on an mem=4G, order-3, data=journal kernel-build
workload; see Results above.
Bo Zhang (4):
mm: compaction: parameterize fragmentation score by order
mm: compaction: target mTHP order for proactive compaction
mm: compaction: skip isolating large folios that already satisfy mTHP
mm: compaction: skip unmovable blocks for non-costly proactive mTHP
compaction
mm/compaction.c | 85 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 68 insertions(+), 17 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH v2 1/4] mm: compaction: parameterize fragmentation score by order
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
@ 2026-10-01 0:14 ` Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction Bo Zhang
` (4 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-01 0:14 UTC (permalink / raw)
To: akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
The proactive compaction fragmentation score functions are hardwired to
COMPACTION_HPAGE_ORDER (typically order-9 for 2MB THP). To later allow
proactive compaction to target other orders (e.g. smaller mTHP orders),
generalize these helpers to take an explicit order argument:
- fragmentation_score_zone(zone, order)
- fragmentation_score_zone_weighted(zone, order)
- fragmentation_score_node(pgdat, order)
All callers pass COMPACTION_HPAGE_ORDER, so this patch is a pure
refactor with no functional change.
Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
---
mm/compaction.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/mm/compaction.c b/mm/compaction.c
index 4994e200bbec..ecd3e6cf54fc 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -2208,16 +2208,16 @@ static bool kswapd_is_running(pg_data_t *pgdat)
/*
* A zone's fragmentation score is the external fragmentation wrt to the
- * COMPACTION_HPAGE_ORDER. It returns a value in the range [0, 100].
+ * given order. It returns a value in the range [0, 100].
*/
-static unsigned int fragmentation_score_zone(struct zone *zone)
+static unsigned int fragmentation_score_zone(struct zone *zone, unsigned int order)
{
- return extfrag_for_order(zone, COMPACTION_HPAGE_ORDER);
+ return extfrag_for_order(zone, order);
}
/*
* A weighted zone's fragmentation score is the external fragmentation
- * wrt to the COMPACTION_HPAGE_ORDER scaled by the zone's size. It
+ * wrt to the given order scaled by the zone's size. It
* returns a value in the range [0, 100].
*
* The scaling factor ensures that proactive compaction focuses on larger
@@ -2225,11 +2225,11 @@ static unsigned int fragmentation_score_zone(struct zone *zone)
* ZONE_DMA32. For smaller zones, the score value remains close to zero,
* and thus never exceeds the high threshold for proactive compaction.
*/
-static unsigned int fragmentation_score_zone_weighted(struct zone *zone)
+static unsigned int fragmentation_score_zone_weighted(struct zone *zone, unsigned int order)
{
unsigned long score;
- score = zone->present_pages * fragmentation_score_zone(zone);
+ score = zone->present_pages * fragmentation_score_zone(zone, order);
return div64_ul(score, zone->zone_pgdat->node_present_pages + 1);
}
@@ -2240,7 +2240,7 @@ static unsigned int fragmentation_score_zone_weighted(struct zone *zone)
* the node's score falls below the low threshold, or one of the back-off
* conditions is met.
*/
-static unsigned int fragmentation_score_node(pg_data_t *pgdat)
+static unsigned int fragmentation_score_node(pg_data_t *pgdat, unsigned int order)
{
unsigned int score = 0;
int zoneid;
@@ -2251,7 +2251,7 @@ static unsigned int fragmentation_score_node(pg_data_t *pgdat)
zone = &pgdat->node_zones[zoneid];
if (!populated_zone(zone))
continue;
- score += fragmentation_score_zone_weighted(zone);
+ score += fragmentation_score_zone_weighted(zone, order);
}
return score;
@@ -2269,12 +2269,13 @@ static unsigned int fragmentation_score_wmark(bool low)
static bool should_proactive_compact_node(pg_data_t *pgdat)
{
int wmark_high;
+ unsigned int order = COMPACTION_HPAGE_ORDER;
if (!sysctl_compaction_proactiveness || kswapd_is_running(pgdat))
return false;
wmark_high = fragmentation_score_wmark(false);
- return fragmentation_score_node(pgdat) > wmark_high;
+ return fragmentation_score_node(pgdat, order) > wmark_high;
}
static enum compact_result __compact_finished(struct compact_control *cc)
@@ -2305,13 +2306,14 @@ static enum compact_result __compact_finished(struct compact_control *cc)
if (cc->proactive_compaction) {
int score, wmark_low;
+ unsigned int order = COMPACTION_HPAGE_ORDER;
pg_data_t *pgdat;
pgdat = cc->zone->zone_pgdat;
if (kswapd_is_running(pgdat))
return COMPACT_PARTIAL_SKIPPED;
- score = fragmentation_score_zone(cc->zone);
+ score = fragmentation_score_zone(cc->zone, order);
wmark_low = fragmentation_score_wmark(true);
if (score > wmark_low)
@@ -3237,10 +3239,11 @@ static int kcompactd(void *p)
timeout = default_timeout;
if (should_proactive_compact_node(pgdat)) {
unsigned int prev_score, score;
+ unsigned int order = COMPACTION_HPAGE_ORDER;
- prev_score = fragmentation_score_node(pgdat);
+ prev_score = fragmentation_score_node(pgdat, order);
compact_node(pgdat, true);
- score = fragmentation_score_node(pgdat);
+ score = fragmentation_score_node(pgdat, order);
/*
* Defer proactive compaction if the fragmentation
* score did not go down i.e. no progress made.
--
2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 1/4] mm: compaction: parameterize fragmentation score by order Bo Zhang
@ 2026-10-01 0:14 ` Bo Zhang
2026-10-19 8:12 ` Dev Jain
2026-10-01 0:14 ` [RFC PATCH v2 3/4] mm: compaction: skip isolating large folios that already satisfy mTHP Bo Zhang
` (3 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: Bo Zhang @ 2026-10-01 0:14 UTC (permalink / raw)
To: akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
Proactive compaction triggers against COMPACTION_HPAGE_ORDER (order-9),
which is too heavyweight and misdirected for mTHP systems where the
pressure is on smaller orders like order-2.
Add compact_hpage_order() to return the highest always-enabled anonymous
mTHP order, and use it as the proactive compaction target in
should_proactive_compact_node(), __compact_finished() and kcompactd().
Fragmentation scores are not comparable across orders, a small order
scores much lower for the same state, so scale the proactive watermarks
down in proportion to the target order, otherwise order-2 would rarely
reach the order-9 threshold.
Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
---
mm/compaction.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/mm/compaction.c b/mm/compaction.c
index ecd3e6cf54fc..3928a5483efc 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -24,6 +24,7 @@
#include <linux/page_owner.h>
#include <linux/psi.h>
#include <linux/cpuset.h>
+#include <linux/huge_mm.h>
#include "page_alloc.h"
#include "internal.h"
@@ -81,6 +82,17 @@ static inline bool is_via_compact_memory(int order) { return false; }
#define COMPACTION_HPAGE_ORDER (PMD_SHIFT - PAGE_SHIFT)
#endif
+static inline int compact_hpage_order(void)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ unsigned long orders = READ_ONCE(huge_anon_orders_always);
+
+ if (orders)
+ return __fls(orders);
+#endif
+ return COMPACTION_HPAGE_ORDER;
+}
+
static struct page *mark_allocated_noprof(struct page *page, unsigned int order, gfp_t gfp_flags)
{
post_alloc_hook(page, order, __GFP_MOVABLE, ALLOC_DEFAULT);
@@ -2257,24 +2269,36 @@ static unsigned int fragmentation_score_node(pg_data_t *pgdat, unsigned int orde
return score;
}
-static unsigned int fragmentation_score_wmark(bool low)
+/*
+ * Fragmentation scores are not comparable across orders: a lower order
+ * scores much lower than a higher order for the same fragmentation state.
+ * Scale the watermark proportionally to the target order so a small order
+ * can still trigger proactive compaction; COMPACTION_HPAGE_ORDER keeps the
+ * original threshold.
+ */
+static unsigned int fragmentation_score_wmark(bool low, unsigned int order)
{
- unsigned int wmark_low, leeway;
+ unsigned int wmark_low, leeway, wmark;
wmark_low = 100U - sysctl_compaction_proactiveness;
leeway = min(10U, wmark_low / 2);
- return low ? wmark_low : min(wmark_low + leeway, 100U);
+ wmark = low ? wmark_low : min(wmark_low + leeway, 100U);
+
+ if (order < COMPACTION_HPAGE_ORDER)
+ wmark = wmark * order / COMPACTION_HPAGE_ORDER;
+
+ return wmark;
}
static bool should_proactive_compact_node(pg_data_t *pgdat)
{
int wmark_high;
- unsigned int order = COMPACTION_HPAGE_ORDER;
+ unsigned int order = compact_hpage_order();
if (!sysctl_compaction_proactiveness || kswapd_is_running(pgdat))
return false;
- wmark_high = fragmentation_score_wmark(false);
+ wmark_high = fragmentation_score_wmark(false, order);
return fragmentation_score_node(pgdat, order) > wmark_high;
}
@@ -2306,7 +2330,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
if (cc->proactive_compaction) {
int score, wmark_low;
- unsigned int order = COMPACTION_HPAGE_ORDER;
+ unsigned int order = compact_hpage_order();
pg_data_t *pgdat;
pgdat = cc->zone->zone_pgdat;
@@ -2314,7 +2338,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
return COMPACT_PARTIAL_SKIPPED;
score = fragmentation_score_zone(cc->zone, order);
- wmark_low = fragmentation_score_wmark(true);
+ wmark_low = fragmentation_score_wmark(true, order);
if (score > wmark_low)
ret = COMPACT_CONTINUE;
@@ -3239,7 +3263,7 @@ static int kcompactd(void *p)
timeout = default_timeout;
if (should_proactive_compact_node(pgdat)) {
unsigned int prev_score, score;
- unsigned int order = COMPACTION_HPAGE_ORDER;
+ unsigned int order = compact_hpage_order();
prev_score = fragmentation_score_node(pgdat, order);
compact_node(pgdat, true);
--
2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH v2 3/4] mm: compaction: skip isolating large folios that already satisfy mTHP
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 1/4] mm: compaction: parameterize fragmentation score by order Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction Bo Zhang
@ 2026-10-01 0:14 ` Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction Bo Zhang
` (2 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-01 0:14 UTC (permalink / raw)
To: akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
When proactive compaction is triggered via compact_memory and mTHP
always-enabled orders are configured, skip isolating folios whose order
is >= the maximum always-enabled mTHP order. These folios already satisfy
mTHP allocation requirements and migrating them is unnecessary overhead.
Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
---
mm/compaction.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/mm/compaction.c b/mm/compaction.c
index 3928a5483efc..0ff454ee5604 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -82,6 +82,15 @@ static inline bool is_via_compact_memory(int order) { return false; }
#define COMPACTION_HPAGE_ORDER (PMD_SHIFT - PAGE_SHIFT)
#endif
+static inline bool mthp_always_enabled(void)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ return !!READ_ONCE(huge_anon_orders_always);
+#else
+ return false;
+#endif
+}
+
static inline int compact_hpage_order(void)
{
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -839,6 +848,12 @@ static bool skip_isolation_on_order(int order, int target_order)
*/
if (!is_via_compact_memory(target_order) && order >= target_order)
return true;
+
+ /* We are compacting for multi-size THP allocation */
+ if (is_via_compact_memory(target_order) && order >= compact_hpage_order() &&
+ mthp_always_enabled())
+ return true;
+
/*
* We limit memory compaction to pageblocks and won't try
* creating free blocks of memory that are larger than that.
--
2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
` (2 preceding siblings ...)
2026-10-01 0:14 ` [RFC PATCH v2 3/4] mm: compaction: skip isolating large folios that already satisfy mTHP Bo Zhang
@ 2026-10-01 0:14 ` Bo Zhang
2026-10-19 9:43 ` Dev Jain
2026-10-19 15:50 ` [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Xueyuan Chen
2026-10-20 14:52 ` Vlastimil Babka (SUSE)
5 siblings, 1 reply; 17+ messages in thread
From: Bo Zhang @ 2026-10-01 0:14 UTC (permalink / raw)
To: akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
Proactive compaction scans all pageblocks including unmovable/reclaimable
ones. For non-costly mTHP orders (<= PAGE_ALLOC_COSTLY_ORDER), those blocks
are dominated by non-migratable kernel allocations (slab, page tables) and
scanning them wastes cycles: a small order is easily satisfied from movable
blocks alone, so there is no need to scavenge the few migratable fallback
pages inside unmovable blocks.
Costly orders keep scanning all blocks: they are hard to form and benefit
from any migratable page available, including allocator fallbacks inside
unmovable blocks.
Restrict non-costly proactive compaction to movable/CMA blocks.
Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
---
mm/compaction.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/compaction.c b/mm/compaction.c
index 0ff454ee5604..deddf931d0f2 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1404,10 +1404,19 @@ static bool suitable_migration_source(struct compact_control *cc,
struct page *page)
{
int block_mt;
+ unsigned int order = compact_hpage_order();
+ bool costly = order > PAGE_ALLOC_COSTLY_ORDER;
if (pageblock_skip_persistent(page))
return false;
+ if (is_via_compact_memory(cc->order) && !costly) {
+ block_mt = get_pageblock_migratetype(page);
+ if (block_mt == MIGRATE_MOVABLE || is_migrate_cma(block_mt))
+ return true;
+ return false;
+ }
+
/*
* Background compaction produces blocks for the zone at
* large, with no particular allocation context. Allow all
--
2.34.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-01 0:14 ` [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction Bo Zhang
@ 2026-10-19 8:12 ` Dev Jain
2026-10-19 14:50 ` Xueyuan Chen
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Dev Jain @ 2026-10-19 8:12 UTC (permalink / raw)
To: Bo Zhang, akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
On 01/10/26 5:44 am, Bo Zhang wrote:
> Proactive compaction triggers against COMPACTION_HPAGE_ORDER (order-9),
> which is too heavyweight and misdirected for mTHP systems where the
> pressure is on smaller orders like order-2.
>
> Add compact_hpage_order() to return the highest always-enabled anonymous
> mTHP order, and use it as the proactive compaction target in
> should_proactive_compact_node(), __compact_finished() and kcompactd().
>
> Fragmentation scores are not comparable across orders, a small order
> scores much lower for the same state, so scale the proactive watermarks
> down in proportion to the target order, otherwise order-2 would rarely
> reach the order-9 threshold.
>
> Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
> ---
> mm/compaction.c | 40 ++++++++++++++++++++++++++++++++--------
> 1 file changed, 32 insertions(+), 8 deletions(-)
>
> diff --git a/mm/compaction.c b/mm/compaction.c
> index ecd3e6cf54fc..3928a5483efc 100644
> --- a/mm/compaction.c
> +++ b/mm/compaction.c
> @@ -24,6 +24,7 @@
> #include <linux/page_owner.h>
> #include <linux/psi.h>
> #include <linux/cpuset.h>
> +#include <linux/huge_mm.h>
> #include "page_alloc.h"
> #include "internal.h"
>
> @@ -81,6 +82,17 @@ static inline bool is_via_compact_memory(int order) { return false; }
> #define COMPACTION_HPAGE_ORDER (PMD_SHIFT - PAGE_SHIFT)
> #endif
>
> +static inline int compact_hpage_order(void)
> +{
> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> + unsigned long orders = READ_ONCE(huge_anon_orders_always);
> +
> + if (orders)
> + return __fls(orders);
> +#endif
> + return COMPACTION_HPAGE_ORDER;
> +}
> +
> static struct page *mark_allocated_noprof(struct page *page, unsigned int order, gfp_t gfp_flags)
> {
> post_alloc_hook(page, order, __GFP_MOVABLE, ALLOC_DEFAULT);
> @@ -2257,24 +2269,36 @@ static unsigned int fragmentation_score_node(pg_data_t *pgdat, unsigned int orde
> return score;
> }
>
> -static unsigned int fragmentation_score_wmark(bool low)
> +/*
> + * Fragmentation scores are not comparable across orders: a lower order
> + * scores much lower than a higher order for the same fragmentation state.
> + * Scale the watermark proportionally to the target order so a small order
> + * can still trigger proactive compaction; COMPACTION_HPAGE_ORDER keeps the
> + * original threshold.
> + */
> +static unsigned int fragmentation_score_wmark(bool low, unsigned int order)
> {
> - unsigned int wmark_low, leeway;
> + unsigned int wmark_low, leeway, wmark;
>
> wmark_low = 100U - sysctl_compaction_proactiveness;
> leeway = min(10U, wmark_low / 2);
> - return low ? wmark_low : min(wmark_low + leeway, 100U);
> + wmark = low ? wmark_low : min(wmark_low + leeway, 100U);
> +
> + if (order < COMPACTION_HPAGE_ORDER)
> + wmark = wmark * order / COMPACTION_HPAGE_ORDER;
> +
> + return wmark;
> }
I wonder if this function should be left alone?
compaction_proactiveness, as I understand is given as a sysfs knob to
ensure that the user can control how much power they want to invest into
compacting. So suppose the value is 20, and the highest mTHP order is
only 2.
This gives wmark = 90 * 2 / 9 = 20. So, even if 80% of the memory can
serve order-2 allocations, we will still perform compaction for order-2.
This seems "extremely proactive" :)
>
> static bool should_proactive_compact_node(pg_data_t *pgdat)
> {
> int wmark_high;
> - unsigned int order = COMPACTION_HPAGE_ORDER;
> + unsigned int order = compact_hpage_order();
>
> if (!sysctl_compaction_proactiveness || kswapd_is_running(pgdat))
> return false;
>
> - wmark_high = fragmentation_score_wmark(false);
> + wmark_high = fragmentation_score_wmark(false, order);
> return fragmentation_score_node(pgdat, order) > wmark_high;
> }
>
> @@ -2306,7 +2330,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
>
> if (cc->proactive_compaction) {
> int score, wmark_low;
> - unsigned int order = COMPACTION_HPAGE_ORDER;
> + unsigned int order = compact_hpage_order();
> pg_data_t *pgdat;
>
> pgdat = cc->zone->zone_pgdat;
> @@ -2314,7 +2338,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
> return COMPACT_PARTIAL_SKIPPED;
>
> score = fragmentation_score_zone(cc->zone, order);
> - wmark_low = fragmentation_score_wmark(true);
> + wmark_low = fragmentation_score_wmark(true, order);
>
> if (score > wmark_low)
> ret = COMPACT_CONTINUE;
> @@ -3239,7 +3263,7 @@ static int kcompactd(void *p)
> timeout = default_timeout;
> if (should_proactive_compact_node(pgdat)) {
> unsigned int prev_score, score;
> - unsigned int order = COMPACTION_HPAGE_ORDER;
> + unsigned int order = compact_hpage_order();
>
> prev_score = fragmentation_score_node(pgdat, order);
> compact_node(pgdat, true);
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction
2026-10-01 0:14 ` [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction Bo Zhang
@ 2026-10-19 9:43 ` Dev Jain
0 siblings, 0 replies; 17+ messages in thread
From: Dev Jain @ 2026-10-19 9:43 UTC (permalink / raw)
To: Bo Zhang, akpm, vbabka, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
On 01/10/26 5:44 am, Bo Zhang wrote:
> Proactive compaction scans all pageblocks including unmovable/reclaimable
> ones. For non-costly mTHP orders (<= PAGE_ALLOC_COSTLY_ORDER), those blocks
> are dominated by non-migratable kernel allocations (slab, page tables) and
> scanning them wastes cycles: a small order is easily satisfied from movable
> blocks alone, so there is no need to scavenge the few migratable fallback
> pages inside unmovable blocks.
>
> Costly orders keep scanning all blocks: they are hard to form and benefit
> from any migratable page available, including allocator fallbacks inside
> unmovable blocks.
I think this is a reasonable compromise for now.
>
> Restrict non-costly proactive compaction to movable/CMA blocks.
>
> Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
> ---
> mm/compaction.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/mm/compaction.c b/mm/compaction.c
> index 0ff454ee5604..deddf931d0f2 100644
> --- a/mm/compaction.c
> +++ b/mm/compaction.c
> @@ -1404,10 +1404,19 @@ static bool suitable_migration_source(struct compact_control *cc,
> struct page *page)
> {
> int block_mt;
> + unsigned int order = compact_hpage_order();
> + bool costly = order > PAGE_ALLOC_COSTLY_ORDER;
>
> if (pageblock_skip_persistent(page))
> return false;
>
> + if (is_via_compact_memory(cc->order) && !costly) {
> + block_mt = get_pageblock_migratetype(page);
> + if (block_mt == MIGRATE_MOVABLE || is_migrate_cma(block_mt))
> + return true;
> + return false;
> + }
> +
> /*
> * Background compaction produces blocks for the zone at
> * large, with no particular allocation context. Allow al
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-19 8:12 ` Dev Jain
@ 2026-10-19 14:50 ` Xueyuan Chen
2026-10-19 15:03 ` Bo Zhang
2026-10-19 15:47 ` Bo Zhang
2 siblings, 0 replies; 17+ messages in thread
From: Xueyuan Chen @ 2026-10-19 14:50 UTC (permalink / raw)
To: dev.jain, zhangbo56
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel, zhangbo0325, Xueyuan Chen
On Mon, Oct 19, 2026 at 01:42:55PM +0530, Dev Jain wrote:
>
>
>On 01/10/26 5:44 am, Bo Zhang wrote:
>> Proactive compaction triggers against COMPACTION_HPAGE_ORDER (order-9),
>> which is too heavyweight and misdirected for mTHP systems where the
>> pressure is on smaller orders like order-2.
>>
>> Add compact_hpage_order() to return the highest always-enabled anonymous
>> mTHP order, and use it as the proactive compaction target in
>> should_proactive_compact_node(), __compact_finished() and kcompactd().
>>
>> Fragmentation scores are not comparable across orders, a small order
>> scores much lower for the same state, so scale the proactive watermarks
>> down in proportion to the target order, otherwise order-2 would rarely
>> reach the order-9 threshold.
>>
>> Signed-off-by: Bo Zhang <zhangbo56@xiaomi.com>
>> ---
>> mm/compaction.c | 40 ++++++++++++++++++++++++++++++++--------
>> 1 file changed, 32 insertions(+), 8 deletions(-)
>>
>> diff --git a/mm/compaction.c b/mm/compaction.c
>> index ecd3e6cf54fc..3928a5483efc 100644
>> --- a/mm/compaction.c
>> +++ b/mm/compaction.c
>> @@ -24,6 +24,7 @@
>> #include <linux/page_owner.h>
>> #include <linux/psi.h>
>> #include <linux/cpuset.h>
>> +#include <linux/huge_mm.h>
>> #include "page_alloc.h"
>> #include "internal.h"
>>
>> @@ -81,6 +82,17 @@ static inline bool is_via_compact_memory(int order) { return false; }
>> #define COMPACTION_HPAGE_ORDER (PMD_SHIFT - PAGE_SHIFT)
>> #endif
>>
>> +static inline int compact_hpage_order(void)
>> +{
>> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> + unsigned long orders = READ_ONCE(huge_anon_orders_always);
>> +
>> + if (orders)
>> + return __fls(orders);
>> +#endif
>> + return COMPACTION_HPAGE_ORDER;
>> +}
>> +
>> static struct page *mark_allocated_noprof(struct page *page, unsigned int order, gfp_t gfp_flags)
>> {
>> post_alloc_hook(page, order, __GFP_MOVABLE, ALLOC_DEFAULT);
>> @@ -2257,24 +2269,36 @@ static unsigned int fragmentation_score_node(pg_data_t *pgdat, unsigned int orde
>> return score;
>> }
>>
>> -static unsigned int fragmentation_score_wmark(bool low)
>> +/*
>> + * Fragmentation scores are not comparable across orders: a lower order
>> + * scores much lower than a higher order for the same fragmentation state.
>> + * Scale the watermark proportionally to the target order so a small order
>> + * can still trigger proactive compaction; COMPACTION_HPAGE_ORDER keeps the
>> + * original threshold.
>> + */
>> +static unsigned int fragmentation_score_wmark(bool low, unsigned int order)
>> {
>> - unsigned int wmark_low, leeway;
>> + unsigned int wmark_low, leeway, wmark;
>>
>> wmark_low = 100U - sysctl_compaction_proactiveness;
>> leeway = min(10U, wmark_low / 2);
>> - return low ? wmark_low : min(wmark_low + leeway, 100U);
>> + wmark = low ? wmark_low : min(wmark_low + leeway, 100U);
>> +
>> + if (order < COMPACTION_HPAGE_ORDER)
>> + wmark = wmark * order / COMPACTION_HPAGE_ORDER;
>> +
>> + return wmark;
>> }
>
>I wonder if this function should be left alone?
>
>compaction_proactiveness, as I understand is given as a sysfs knob to
>ensure that the user can control how much power they want to invest into
>compacting. So suppose the value is 20, and the highest mTHP order is
>only 2.
>
>This gives wmark = 90 * 2 / 9 = 20. So, even if 80% of the memory can
>serve order-2 allocations, we will still perform compaction for order-2.
>This seems "extremely proactive" :)
My understanding is that compaction for lower orders is cheaper, so lower
thresholds could help reduce mTHP allocation fallbacks at an acceptable
cost. Is that the idea?
>
>>
>> static bool should_proactive_compact_node(pg_data_t *pgdat)
>> {
>> int wmark_high;
>> - unsigned int order = COMPACTION_HPAGE_ORDER;
>> + unsigned int order = compact_hpage_order();
>>
>> if (!sysctl_compaction_proactiveness || kswapd_is_running(pgdat))
>> return false;
>>
>> - wmark_high = fragmentation_score_wmark(false);
>> + wmark_high = fragmentation_score_wmark(false, order);
>> return fragmentation_score_node(pgdat, order) > wmark_high;
>> }
>>
>> @@ -2306,7 +2330,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
>>
>> if (cc->proactive_compaction) {
>> int score, wmark_low;
>> - unsigned int order = COMPACTION_HPAGE_ORDER;
>> + unsigned int order = compact_hpage_order();
>> pg_data_t *pgdat;
>>
>> pgdat = cc->zone->zone_pgdat;
>> @@ -2314,7 +2338,7 @@ static enum compact_result __compact_finished(struct compact_control *cc)
>> return COMPACT_PARTIAL_SKIPPED;
>>
>> score = fragmentation_score_zone(cc->zone, order);
>> - wmark_low = fragmentation_score_wmark(true);
>> + wmark_low = fragmentation_score_wmark(true, order);
>>
>> if (score > wmark_low)
>> ret = COMPACT_CONTINUE;
>> @@ -3239,7 +3263,7 @@ static int kcompactd(void *p)
>> timeout = default_timeout;
>> if (should_proactive_compact_node(pgdat)) {
>> unsigned int prev_score, score;
>> - unsigned int order = COMPACTION_HPAGE_ORDER;
>> + unsigned int order = compact_hpage_order();
>>
>> prev_score = fragmentation_score_node(pgdat, order);
>> compact_node(pgdat, true);
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-19 8:12 ` Dev Jain
2026-10-19 14:50 ` Xueyuan Chen
@ 2026-10-19 15:03 ` Bo Zhang
2026-10-20 6:48 ` Dev Jain
2026-10-19 15:47 ` Bo Zhang
2 siblings, 1 reply; 17+ messages in thread
From: Bo Zhang @ 2026-10-19 15:03 UTC (permalink / raw)
To: dev.jain
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel, Bo Zhang
On 19/10/26 1:42 pm, Dev Jain wrote:
> I wonder if this function should be left alone?
>
> compaction_proactiveness, as I understand is given as a sysfs knob to
> ensure that the user can control how much power they want to invest into
> compacting. So suppose the value is 20, and the highest mTHP order is
> only 2. This gives wmark = 90 * 2 / 9 = 20. So, even if 80% of the memory
> can serve order-2 allocations, we will still perform compaction for
> order-2. This seems "extremely proactive" :)
Thanks a lot for looking at this closely, and you are right that the
scaling factor is the weakest part of this patch. I called it out as an
open question in the cover letter and I don't have a solid theoretical
basis for the linear order/COMPACTION_HPAGE_ORDER form.
What pushed me towards scaling the watermark at all was the opposite
problem on the measurement side: without any scaling, the order-9
threshold is essentially never reached for a small order, so proactive
compaction effectively never runs for order-2.
I instrumented fragmentation_score_node() for order-2 on an 8G,
data=journal kernel-build workload and sampled it at ~100ms. On the
unpatched kernel the order-2 score looks like this:
order-2 score (unpatched, same workload):
mean 17.3
p90 47
p99 91
max 100
fraction of time the score exceeds a given threshold:
> 90 (unscaled, the current order-9 wmark): 1.0%
> 20 (scaled down to order-2): 27.2%
So with the current (unscaled) watermark, the order-2 score crosses the
trigger only 1% of the time, which in practice proactive compaction almost
never fires for order-2.
That said, your example shows the linear scaling clearly overshoots in
the other direction: a scaled wmark of ~20 can keep compacting while a
large fraction of memory is already usable, which is not what the
proactiveness knob is supposed to express. So I agree the current formula
is not the right answer.
I'd appreciate your thoughts on the direction here. A couple of options
I can see:
1. Leave fragmentation_score_wmark() alone and instead make the score
itself order-aware / normalized, so that a given proactiveness value
maps to a comparable amount of work regardless of the target order.
This keeps the knob's meaning intact.
2. Keep scaling the watermark but with a floor / non-linear mapping so
it cannot collapse to a value that triggers when memory is clearly
sufficient.
I haven't settled on either yet and would rather hear which direction you
think makes more sense before reworking it.
Also, thanks for the review on patch 4 -- good to know the
costly/non-costly split seems like a reasonable compromise.
Thanks,
Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-19 8:12 ` Dev Jain
2026-10-19 14:50 ` Xueyuan Chen
2026-10-19 15:03 ` Bo Zhang
@ 2026-10-19 15:47 ` Bo Zhang
2 siblings, 0 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-19 15:47 UTC (permalink / raw)
To: dev.jain
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel
[Resending: my earlier copy does not seem to have reached the list.
Apologies to anyone receiving this twice.]
On 19/10/26 1:42 pm, Dev Jain wrote:
> I wonder if this function should be left alone?
>
> compaction_proactiveness, as I understand is given as a sysfs knob to
> ensure that the user can control how much power they want to invest into
> compacting. So suppose the value is 20, and the highest mTHP order is
> only 2. This gives wmark = 90 * 2 / 9 = 20. So, even if 80% of the memory
> can serve order-2 allocations, we will still perform compaction for
> order-2. This seems "extremely proactive" :)
Thanks a lot for looking at this closely, and you are right that the
scaling factor is the weakest part of this patch. I called it out as an
open question in the cover letter and I don't have a solid theoretical
basis for the linear order/COMPACTION_HPAGE_ORDER form.
What pushed me towards scaling the watermark at all was the opposite
problem on the measurement side: without any scaling, the order-9
threshold is essentially never reached for a small order, so proactive
compaction effectively never runs for order-2.
I instrumented fragmentation_score_node() for order-2 on an 8G,
data=journal kernel-build workload and sampled it at ~100ms. On the
unpatched kernel the order-2 score looks like this:
order-2 score (unpatched, same workload):
mean 17.3
p90 47
p99 91
max 100
fraction of time the score exceeds a given threshold:
> 90 (unscaled, the current order-9 wmark): 1.0%
> 20 (scaled down to order-2): 27.2%
So with the current (unscaled) watermark, the order-2 score crosses the
trigger only 1% of the time, which in practice proactive compaction almost
never fires for order-2.
That said, your example shows the linear scaling clearly overshoots in
the other direction: a scaled wmark of ~20 can keep compacting while a
large fraction of memory is already usable, which is not what the
proactiveness knob is supposed to express. So I agree the current formula
is not the right answer.
I'd appreciate your thoughts on the direction here. A couple of options
I can see:
1. Leave fragmentation_score_wmark() alone and instead make the score
itself order-aware / normalized, so that a given proactiveness value
maps to a comparable amount of work regardless of the target order.
This keeps the knob's meaning intact.
2. Keep scaling the watermark but with a floor / non-linear mapping so
it cannot collapse to a value that triggers when memory is clearly
sufficient.
I haven't settled on either yet and would rather hear which direction you
think makes more sense before reworking it.
Also, thanks for the review on patch 4 -- good to know the
costly/non-costly split seems like a reasonable compromise.
Thanks,
Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
` (3 preceding siblings ...)
2026-10-01 0:14 ` [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction Bo Zhang
@ 2026-10-19 15:50 ` Xueyuan Chen
2026-10-20 14:52 ` Vlastimil Babka (SUSE)
5 siblings, 0 replies; 17+ messages in thread
From: Xueyuan Chen @ 2026-10-19 15:50 UTC (permalink / raw)
To: zhangbo0325
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel, zhangbo56, Xueyuan Chen
On Thu, Oct 01, 2026 at 08:14:08AM +0800, Bo Zhang wrote:
>Hi all,
>
>This series improves memory compaction to better serve mTHP (multi-size
>THP) allocations, particularly for small orders like order-2 (16KB).
>The changes focus on the proactive (kcompactd) compaction path.
>
>Problem:
>
>The current proactive compaction targets COMPACTION_HPAGE_ORDER (order-9,
>2MB), which is unfriendly to mTHP in two ways:
>
>1. It migrates folios that already satisfy mTHP allocation needs. For
> example, an order-2 folio is a valid mTHP page, yet compaction still
> moves it around trying to form order-9 blocks. This is unnecessary
> work and wastes energy.
>
>2. Compaction designed for 2MB huge pages is too heavyweight for mTHP.
> mTHP allocations are frequent and only require small contiguous blocks
> (e.g., 4 pages for order-2). A lighter-weight, mTHP-aware compaction
> strategy is needed to reduce overhead and power consumption.
>
>Approach:
>
>This series makes four changes:
>
>1. Generalize the fragmentation score functions to accept an order
> parameter. This is a pure refactor with no functional change; all
> callers still pass COMPACTION_HPAGE_ORDER.
>
>2. Use the highest always-enabled mTHP order as the proactive compaction
> target. Because a fragmentation score for a small order is naturally
> much lower than for order-9 under the same fragmentation state, the
> proactive watermark is scaled down in proportion to the target order;
> otherwise a small order would almost never reach the trigger threshold.
>
>3. During proactive compaction (compact_memory), skip isolating folios
> that already satisfy mTHP requirements, avoiding unnecessary migration
> overhead.
>
>4. For non-costly mTHP orders, restrict proactive compaction to movable
> (and CMA) pageblocks. Unmovable/reclaimable blocks are dominated by
> non-migratable kernel allocations. scanning them wastes cycles because
> a small order can be satisfied from movable blocks alone. Costly orders
> keep scanning all blocks, since they are harder to form and benefit
> from any migratable page available.
>
>Test setup:
>
>x86 host, arm64 cross-build (defconfig + CONFIG_DEBUG_INFO=y,
>CONFIG_DEBUG_INFO_DWARF5=y), booted with mem=4G. order-3 (32KB) mTHP is
>set to "always"; ext4 root mounted data=journal. The kernel build
>naturally fragments order-3 free memory during the run.
>
>Runtime (two defrag modes were tested, see Results):
> echo always > .../hugepages-32kB/enabled
> echo madvise > .../transparent_hugepage/defrag # or: always
> echo 20 > /proc/sys/vm/compaction_proactiveness
>
>A background loop keeps proactiveness poked every 100ms so kcompactd
>re-evaluates promptly (its default 500ms interval is too coarse to catch
>the transient order-3 fragmentation peaks under this workload):
>
> while true; do
> echo 20 > /proc/sys/vm/compaction_proactiveness
> sleep 0.1
> done
>
>Workload: make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- vmlinux -j28
>5 rounds per configuration; each round: make clean + drop_caches, then
>counter deltas around the build. The baseline is the unmodified kernel.
>
>Results (5-round means). anon_fault_alloc is within 1% between kernels,
>so the fallback numbers are directly comparable.
>
>defrag=madvise:
> w/o patch w/ patch change
> -------------------------- ----------- ----------- --------
> anon_fault_alloc 14,307,597 14,401,699 +1%
> anon_fault_fallback 97,701 40,975 -58%
> fallback ratio 0.68% 0.28%
> compact_isolated 8,479,773 1,458,949 -83%
> compact_migrate_scanned 78,198,828 22,900,359 -71%
> kcompactd cpu (s) 43 7 -84%
> sys (kernel build) 6m34s 6m34s ~0%
>
>defrag=always:
> w/o patch w/ patch change
> -------------------------- ----------- ----------- --------
> anon_fault_alloc 14,370,984 14,404,234 ~0%
> anon_fault_fallback 619 823
> compact_stall 979 585 -40%
> compact_isolated 6,390,940 2,431,800 -62%
> compact_migrate_scanned 86,171,095 46,339,911 -46%
> kcompactd cpu (s) 36 13 -62%
> sys (kernel build) 6m34s 6m27s -1.8%
>
>1. With defrag=madvise, the patch cuts mTHP fallback by 58% (ratio
> 0.68% -> 0.28%).
>
>2. With defrag=always, direct compaction already keeps fallback near
> zero, and the patch instead cuts direct compaction stalls by 40%.
>
>In both cases the compaction is done far more cheaply (kcompactd CPU
>-62..84%, compact_isolated/scanned -46..83%).
Hi Bo,
With proactive compaction enabled, have you measured the change in power
consumption on Android devices after applying this patch series?
>
>Open questions:
>
>1. In skip_isolation_on_order() and elsewhere, the target order is read
> from huge_anon_orders_always directly, since during proactive
> compaction cc->order is -1 (via compact_memory) and there is no clean
> way to plumb the mTHP order down. This variable can change under
> userspace at any time, making the semantics fragile. Ideas on how to
> pass the target order through the proactive path cleanly are welcome.
>
>2. The proactive watermark is scaled linearly by the target order
> (wmark * order / COMPACTION_HPAGE_ORDER). This is empirical; a more
> principled cross-order normalization of the fragmentation score would
> be welcome.
>
>Changes since v1
>================
>
>The series is now scoped to the proactive compaction path only. Two
>patches from v1 were dropped, and two new mechanisms were added:
>
>- Dropped v1 patch 3 ("don't skip proactive compaction for non-costly
> mTHP", i.e. running proactive compaction concurrently with kswapd).
> Follow-up testing showed it lowered fallback mainly by driving extra
> anonymous reclaim/swap rather than by better compaction; keeping the
> original kswapd back-off avoids trading workingset for mTHP fallback.
>
>- Dropped v1 patch 4 (mTHP-aware zone_effective_free_pages() watermark):
> it added reclaim pressure without a clear net benefit in this scope.
>
>- Split the former patch 1 into a pure refactor (parameterize the
> fragmentation score by order) plus the mTHP-targeting change, so the
> mechanical and behavioural parts can be reviewed independently.
>
>- Added the proactive watermark scaling by target order, so a small mTHP
> order can actually reach the trigger threshold.
>
>- Added patch 4 (skip unmovable blocks for non-costly proactive mTHP
> compaction). Without it, proactive compaction wastes most of its
> scanning on unmovable blocks full of kernel allocations; with it,
> kcompactd's CPU and the scanned/isolated counters drop by an order of
> magnitude while fallback still improves.
>
>- compact_hpage_order() uses __fls() (highest always-enabled mTHP order)
> guarded by #ifdef CONFIG_TRANSPARENT_HUGEPAGE (m68k allmodconfig build
> fix from the kernel test robot).
>
>- Refreshed test data on an mem=4G, order-3, data=journal kernel-build
> workload; see Results above.
>
>Bo Zhang (4):
> mm: compaction: parameterize fragmentation score by order
> mm: compaction: target mTHP order for proactive compaction
> mm: compaction: skip isolating large folios that already satisfy mTHP
> mm: compaction: skip unmovable blocks for non-costly proactive mTHP
> compaction
>
> mm/compaction.c | 85 +++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 68 insertions(+), 17 deletions(-)
>
>--
>2.34.1
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-19 15:03 ` Bo Zhang
@ 2026-10-20 6:48 ` Dev Jain
2026-10-21 6:18 ` Bo Zhang
0 siblings, 1 reply; 17+ messages in thread
From: Dev Jain @ 2026-10-20 6:48 UTC (permalink / raw)
To: Bo Zhang
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel, Bo Zhang
On 19/10/26 8:33 pm, Bo Zhang wrote:
> On 19/10/26 1:42 pm, Dev Jain wrote:
>> I wonder if this function should be left alone?
>>
>> compaction_proactiveness, as I understand is given as a sysfs knob to
>> ensure that the user can control how much power they want to invest into
>> compacting. So suppose the value is 20, and the highest mTHP order is
>> only 2. This gives wmark = 90 * 2 / 9 = 20. So, even if 80% of the memory
>> can serve order-2 allocations, we will still perform compaction for
>> order-2. This seems "extremely proactive" :)
>
> Thanks a lot for looking at this closely, and you are right that the
> scaling factor is the weakest part of this patch. I called it out as an
> open question in the cover letter and I don't have a solid theoretical
> basis for the linear order/COMPACTION_HPAGE_ORDER form.
>
> What pushed me towards scaling the watermark at all was the opposite
> problem on the measurement side: without any scaling, the order-9
> threshold is essentially never reached for a small order, so proactive
> compaction effectively never runs for order-2.
>
> I instrumented fragmentation_score_node() for order-2 on an 8G,
> data=journal kernel-build workload and sampled it at ~100ms. On the
> unpatched kernel the order-2 score looks like this:
>
> order-2 score (unpatched, same workload):
> mean 17.3
> p90 47
> p99 91
> max 100
>
> fraction of time the score exceeds a given threshold:
> > 90 (unscaled, the current order-9 wmark): 1.0%
> > 20 (scaled down to order-2): 27.2%
>
> So with the current (unscaled) watermark, the order-2 score crosses the
> trigger only 1% of the time, which in practice proactive compaction almost
> never fires for order-2.
I get it, so the workload is rapidly allocating mTHP, and kcompactd does not
kick in time, leading to direct compaction (compact_stall) or fallback.
But I think this is a tradeoff with the current design in Linux and has nothing
to do with our mTHP usecase right? Even with PMD sized THP we may have the same
problem.
I think the uncontroversial bit of your patchset is the fact that currently we
migrate large folios just to free up a 2M region. To make forward progress it
will be great if you can find a workload which gets us an improvement without
the threshold changes and we could get those patches merged first.
I am saying that because the reason you keep crossing the 90% threshold is
due to the nature of the workload and that you set 32k mTHP to always. I doubt
on a real system you will cross the threshold this rapidly since mTHP would be
mostly "madvise" and that mTHP-requiring workload wouldn't be the only workload
running.
Given that, one thing that comes to mind is this algorithm - kcompactd wakes up, sees
that the threshold got crossed again, which means it woke up too late. So
it should manipulate the threshold or its wake up time. We need a signal to
say that the mTHP allocation is too abundant and we need background compaction
more frequently.
This algorithm may be in contradiction with the sysctl ... so instead of changing
the threshold, we could lower the wakeup time.
This is similar to how the pcp list changes its threshold if too much allocation
is happening.
>
> That said, your example shows the linear scaling clearly overshoots in
> the other direction: a scaled wmark of ~20 can keep compacting while a
> large fraction of memory is already usable, which is not what the
> proactiveness knob is supposed to express. So I agree the current formula
> is not the right answer.
>
> I'd appreciate your thoughts on the direction here. A couple of options
> I can see:
>
> 1. Leave fragmentation_score_wmark() alone and instead make the score
> itself order-aware / normalized, so that a given proactiveness value
> maps to a comparable amount of work regardless of the target order.
> This keeps the knob's meaning intact.
The challenge is the normalization algorithm, the problem is that there is
nothing we can deduce apart from the fact that
frag_score (order x) <= frag_score (order y) where x <= y.
>
> 2. Keep scaling the watermark but with a floor / non-linear mapping so
> it cannot collapse to a value that triggers when memory is clearly
> sufficient.
>
> I haven't settled on either yet and would rather hear which direction you
> think makes more sense before reworking it.
>
> Also, thanks for the review on patch 4 -- good to know the
> costly/non-costly split seems like a reasonable compromise.
>
> Thanks,
> Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
` (4 preceding siblings ...)
2026-10-19 15:50 ` [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Xueyuan Chen
@ 2026-10-20 14:52 ` Vlastimil Babka (SUSE)
2026-10-21 6:00 ` Bo Zhang
5 siblings, 1 reply; 17+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-10-20 14:52 UTC (permalink / raw)
To: Bo Zhang, akpm, david
Cc: surenb, mhocko, brendan.jackman, hannes, ziy, ljs, liam, rppt,
qi.zheng, shakeel.butt, kasong, baohua, axelrasmussen, yuanchu,
weixugc, zhaonanzhe, lipengfei28, linux-mm, linux-kernel,
Bo Zhang
On 10/1/26 02:14, Bo Zhang wrote:
> Open questions:
>
> 1. In skip_isolation_on_order() and elsewhere, the target order is read
> from huge_anon_orders_always directly, since during proactive
> compaction cc->order is -1 (via compact_memory) and there is no clean
> way to plumb the mTHP order down.
Isn't using struct compact_control clean enough? There's already many
fields like
bool direct_compaction; /* False from kcompactd or /proc/... */
bool proactive_compaction; /* kcompactd proactive compaction */
Who says is_via_compact_memory() cannot be refactored into something using
these kinds of fields and not 'order' being -1, which could be then used as
the target order.
> This variable can change under
> userspace at any time, making the semantics fragile. Ideas on how to
> pass the target order through the proactive path cleanly are welcome.
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
2026-10-20 14:52 ` Vlastimil Babka (SUSE)
@ 2026-10-21 6:00 ` Bo Zhang
2026-10-21 9:31 ` Vlastimil Babka (SUSE)
0 siblings, 1 reply; 17+ messages in thread
From: Bo Zhang @ 2026-10-21 6:00 UTC (permalink / raw)
To: vbabka
Cc: akpm, david, surenb, mhocko, brendan.jackman, hannes, ziy, ljs,
liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel
On 10/20/26 16:52, Vlastimil Babka (SUSE) wrote:
> Isn't using struct compact_control clean enough? There's already many
> fields like
> bool direct_compaction; /* False from kcompactd or /proc/... */
> bool proactive_compaction; /* kcompactd proactive compaction */
>
> Who says is_via_compact_memory() cannot be refactored into something using
> these kinds of fields and not 'order' being -1, which could be then used as
> the target order.
Thanks, that's a much cleaner direction than reading huge_anon_orders_always
and would also address the race I raised in the second open question.
I tried to work out what it takes, and ran into one thing I'd like your
opinion on before committing to an approach.
Today order == -1 (is_via_compact_memory()) covers two callers that both go
through compact_node():
- proactive compaction (proactive_compaction = true, order = -1)
- /proc/sys/vm/compact_memory (proactive_compaction = false, order = -1)
and the real order-carrying callers are:
- direct compaction (direct_compaction = true, order > 0)
- kcompactd normal work (direct_compaction = false, order > 0)
The issue is that /proc/sys/vm/compact_memory and kcompactd normal work
differ only in the order value (-1 vs > 0), and both have direct_compaction =
= false and proactive_compaction == false. So with the existing bool fields
aloneI can't reproduce is_via_compact_memory() exactly without adding a new
field, which I'd rather avoid.
If instead I give proactive compaction a real target order (and keep
compact_memory on order == -1), the ambiguity goes away, but giving proactive
a real order is not behaviour-neutral: several paths that proactive currently
skips because order <= -1 would start running. I went through them:
1) skip_isolation_on_order() - currently proactive takes the pageblock_order
branch, because target_order == -1 short-circuits the first test:
if (!is_via_compact_memory(target_order) && order >= target_order)
return true;
With a real target order the test starts applying and would skip isolating
folios with order >= target_order. That is close to what patch 3 does, but
not identical: patch 3 tests order >= compact_hpage_order() and
additionally gates on mthp_always_enabled(), whereas the native test keys
off target_order directly. Whether patch 3 can be folded into this depends
on exactly how the proactive target order is set, so I'd treat that as a
follow-up rather than a given.
2) fast_isolate_freepages() - currently returns early for proactive:
/* Full compaction passes in a negative order */
if (cc->order <= 0)
return;
Here the order == -1 is doing something deliberate: it keeps full
compaction out of the fast freelist search and on the linear free scanner.
The fast search is meant to grab enough free pages of a specific order
for direct compaction and stops early, which is at odds with proactive's
goal of scanning broadly. With a real target order proactive would start
taking the fast path, so my plan is to preserve the current behaviour with
an explicit guard:
if (cc->order <= 0 || cc->proactive_compaction)
return;
3) suitable_migration_target() - the free-block test changes:
int order = cc->order > 0 ? cc->order : pageblock_order;
A free buddy page is rejected as a migration target when its order is
>= this value. For proactive today the threshold is pageblock_order, so
only very large free blocks are skipped; with a real target order it drops
to the mTHP order. To keep proactive's behaviour unchanged here too, I'd
keep the threshold at pageblock_order for proactive, i.e. gate on
proactive_compaction rather than let the real order take effect.
4) compact_zone() end-of-loop drain - this becomes active:
if (cc->order > 0 && last_migrated_pfn) { ... lru drain ... }
(capture is not a concern here, proactive passes capc == NULL.) This one
is harmless, but for consistency I'd keep it gated off for proactive along
with (2) and (3), so the order change does not alter the proactive path.
5) compact_zone() start - this watermark check starts running for proactive:
if (!is_via_compact_memory(cc->order)) {
ret = compaction_suit_allocation_order(cc->zone, cc->order, ...);
if (ret != COMPACT_CONTINUE)
return ret;
}
This one is different from (2)-(4): it may actually be worth having for
proactive, so I've left it for discussion below rather than gating it off.
A couple of paths are not affected, since proactive already diverges there
via existing flags: __compact_finished() handles proactive earlier through
cc->proactive_compaction, and fast_find_migrateblock() returns early because
proactive sets ignore_skip_hint.
So my plan would be to let cc->order carry the real target order, but gate
(2), (3) and (4) on cc->proactive_compaction so the proactive path keeps its
current broad-scan behaviour - i.e. the order change is purely about the
target, not about switching on direct-compaction paths.
The one I'd genuinely like your opinion on is (5): the
compaction_suit_allocation_order() watermark check. Unlike the others, this
one might actually be desirable for proactive - it would stop proactive from
compacting when the order is already satisfied by the watermark, which is
close to the "don't compact when memory is already sufficient" point Dev
raised on the sibling thread. But it layers a watermark gate on top of the
fragmentation-score logic that drives proactive today, and I'm not sure the
two should be mixed. Would you let this one take effect for proactive, or
keep it gated off like the rest?
The other open point is the one you raised: compact_memory and
kcompactd-normal work can only be told apart by the order today (both have
direct_compaction == false, proactive_compaction == false). So a fully
behaviour-neutral "bool instead of order == -1" cleanup isn't quite possible
without a new field. Do you see adding a field as off the table, or is it
acceptable here?
Thanks,
Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction
2026-10-20 6:48 ` Dev Jain
@ 2026-10-21 6:18 ` Bo Zhang
0 siblings, 0 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-21 6:18 UTC (permalink / raw)
To: dev.jain
Cc: akpm, vbabka, david, surenb, mhocko, brendan.jackman, hannes,
ziy, ljs, liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel
On 20/10/26 12:18 pm, Dev Jain wrote:
> I get it, so the workload is rapidly allocating mTHP, and kcompactd does not
> kick in time, leading to direct compaction (compact_stall) or fallback.
>
> But I think this is a tradeoff with the current design in Linux and has
> nothing to do with our mTHP usecase right? Even with PMD sized THP we may
> have the same problem.
Agreed, the underlying "kcompactd reacts too late" tradeoff isn't specific to
mTHP. mTHP just makes it easier to hit because the allocations are frequent
and small.
> I think the uncontroversial bit of your patchset is the fact that currently
> we migrate large folios just to free up a 2M region. To make forward progress
> it will be great if you can find a workload which gets us an improvement
> without the threshold changes and we could get those patches merged first.
That makes sense to me, and I'm happy to split it this way - get the
uncontroversial "don't migrate folios that already satisfy the target" part
in first, separate from the threshold discussion.
One caveat: the exact shape of that part (patch 3) is tied to the cc->order
refactor Vlastimil suggested on the cover-letter thread. If proactive carries
a real target order, skip_isolation_on_order() largely covers patch 3 on its
own; if we keep order == -1, patch 3 stays as a separate check. So I'd like
to settle that refactor direction with Vlastimil first, then post the
uncontroversial part in whatever form falls out of it, to avoid reworking it
twice.
> I am saying that because the reason you keep crossing the 90% threshold is
> due to the nature of the workload and that you set 32k mTHP to always. I doubt
> on a real system you will cross the threshold this rapidly since mTHP would be
> mostly "madvise" and that mTHP-requiring workload wouldn't be the only
> workload running.
Fair point, and I should be upfront about it: with madvise, or when higher
order fallback is acceptable, you're right that there won't be nearly as
many moments where the score is high enough to warrant compaction.
> Given that, one thing that comes to mind is this algorithm - kcompactd wakes
> up, sees that the threshold got crossed again, which means it woke up too
> late. So it should manipulate the threshold or its wake up time. We need a
> signal to say that the mTHP allocation is too abundant and we need background
> compaction more frequently.
> This algorithm may be in contradiction with the sysctl ... so instead of
> changing the threshold, we could lower the wakeup time.
Adjusting the wakeup time is a reasonable idea, but I have a worry that it
may not reach the actual bottleneck for small orders. Once kcompactd wakes
up it still has to pass should_proactive_compact_node(), i.e. score > wmark,
before it does any work. For order-2 the fragmentation score itself stays
small (mean ~17 in my runs, vs the unscaled order-9 wmark of ~90), so no
matter how often kcompactd wakes up, the score won't reach the threshold
and it won't compact.
I actually have a data point for this: the 100ms loop I used in the cover
letter already drives the wakeup frequency very high, and even then, when the
score is small, it simply doesn't trigger compaction - more frequent wakeups
don't help if the check that follows never passes. So waking up more often
and lowering the threshold seem to address different stages: frequency
controls how often we check, the threshold controls whether a check for a
small order can ever decide to compact. That's why I don't think wakeup
tuning alone replaces the threshold question, though I agree it could help
on top of it.
Thanks,
Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
2026-10-21 6:00 ` Bo Zhang
@ 2026-10-21 9:31 ` Vlastimil Babka (SUSE)
2026-10-21 12:31 ` Bo Zhang
0 siblings, 1 reply; 17+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-10-21 9:31 UTC (permalink / raw)
To: Bo Zhang
Cc: akpm, david, surenb, mhocko, brendan.jackman, hannes, ziy, ljs,
liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel
On 10/21/26 08:00, Bo Zhang wrote:
> On 10/20/26 16:52, Vlastimil Babka (SUSE) wrote:
>> Isn't using struct compact_control clean enough? There's already many
>> fields like
>> bool direct_compaction; /* False from kcompactd or /proc/... */
>> bool proactive_compaction; /* kcompactd proactive compaction */
>>
>> Who says is_via_compact_memory() cannot be refactored into something using
>> these kinds of fields and not 'order' being -1, which could be then used as
>> the target order.
>
> Thanks, that's a much cleaner direction than reading huge_anon_orders_always
> and would also address the race I raised in the second open question.
>
> I tried to work out what it takes, and ran into one thing I'd like your
> opinion on before committing to an approach.
I'm not going to answer your LLM's questions for you.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction
2026-10-21 9:31 ` Vlastimil Babka (SUSE)
@ 2026-10-21 12:31 ` Bo Zhang
0 siblings, 0 replies; 17+ messages in thread
From: Bo Zhang @ 2026-10-21 12:31 UTC (permalink / raw)
To: vbabka
Cc: akpm, david, surenb, mhocko, brendan.jackman, hannes, ziy, ljs,
liam, rppt, qi.zheng, shakeel.butt, kasong, baohua,
axelrasmussen, yuanchu, weixugc, zhaonanzhe, lipengfei28,
linux-mm, linux-kernel
On 10/21/26 11:31, Vlastimil Babka (SUSE) wrote:
> I'm not going to answer your LLM's questions for you.
Sorry for the previous mail, which polished my English by AI.
Let me put it in my own words.
Last mail you advised me to use cc->order to pass the target order,
however /proc/sys/vm/compact_memory and kcompactd work could
only be distinguished by order. Because in both cases the variable
direct_compaction and proactive_compaction are false.
Without adding new members to compact_control, it's impossible
to use the bool instead of is_via_compact_memory to achieve the
same goal (Or maybe I missed something)
For skip_isolation_on_order, I want the new logic to take effect:
with a real order it will skip folios already >= the target order.
This is what patch 3 does.
I will keep the original behaviour for fast_isolate_freepages,
suitable_migration_target and compact_zone functions. I will use
the bool variables to express the same logic.
But in compact_zone, should we exit the compaction when the order
is already satisfied by the watermark? That is I want to discuss.
Thanks
Bo
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-10-21 12:32 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01 0:14 [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 1/4] mm: compaction: parameterize fragmentation score by order Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 2/4] mm: compaction: target mTHP order for proactive compaction Bo Zhang
2026-10-19 8:12 ` Dev Jain
2026-10-19 14:50 ` Xueyuan Chen
2026-10-19 15:03 ` Bo Zhang
2026-10-20 6:48 ` Dev Jain
2026-10-21 6:18 ` Bo Zhang
2026-10-19 15:47 ` Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 3/4] mm: compaction: skip isolating large folios that already satisfy mTHP Bo Zhang
2026-10-01 0:14 ` [RFC PATCH v2 4/4] mm: compaction: skip unmovable blocks for non-costly proactive mTHP compaction Bo Zhang
2026-10-19 9:43 ` Dev Jain
2026-10-19 15:50 ` [RFC PATCH v2 0/4] mm: compaction: mTHP-friendly memory compaction Xueyuan Chen
2026-10-20 14:52 ` Vlastimil Babka (SUSE)
2026-10-21 6:00 ` Bo Zhang
2026-10-21 9:31 ` Vlastimil Babka (SUSE)
2026-10-21 12:31 ` Bo Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®