* [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes
@ 2026-07-21 13:56 SJ Park
2026-07-21 14:07 ` sashiko-bot
0 siblings, 1 reply; 3+ messages in thread
From: SJ Park @ 2026-07-21 13:56 UTC (permalink / raw)
To: Andrew Morton
Cc: Jiahui Zhang, Honggyu Kim, SJ Park, damon, linux-kernel, linux-mm
From: Jiahui Zhang <jiahuitry@outlook.com>
DAMOS_MIGRATE_{HOT,COLD} passes a target NUMA node to migrate_pages().
But alloc_migration_target() only treats mtc->nid as a preferred node
unless __GFP_THISNODE is set. Hence target allocation can fall back
to another node, and migrate_pages() can report success without placing
the folio on the requested target node.
Consider a two-node tiered system where node 0 is a fast tier and node 1
is a CPU-less slow tier such as CXL memory, and the user wants to promote
hot regions from node 1 to node 0 with a command like:
sudo damo start --ops vaddr --target_pid ${workload_pid} \
--damos_action migrate_hot 0 \
--damos_access_rate 70% max
Without the __GFP_THISNODE flag, when the memory allocator finds that
node 0 is nearly full, it can fall back to node 1 without waking up
kswapd. Then the pages allocated for migrate_pages() are still on node 1,
and the regions that are expected to be promoted to node 0 are only moved
to different physical pages on node 1.
Meanwhile, both the mm_migrate_pages tracepoint and DAMOS's own
sz_applied statistics (reported via the damos_stat_after_apply_interval
tracepoint) show the migrations as successful, which makes the failure
practically invisible and hard to investigate.
Running a demotion-purpose DAMOS scheme alongside the promotion scheme
does not fully avoid this either. If demotion cannot keep up with the
promotion rate, allocation can still fall back to node 1 during
promotion, and the same misleading statistics show up.
Make DAMON's migration target allocation strict by setting
__GFP_THISNODE, so that a failed allocation on the target node is
reported as a failure instead of silently landing on a different node.
This is consistent with alloc_misplaced_dst_folio(), alloc_demote_folio(),
and with do_move_pages_to_node(), which all use __GFP_THISNODE for
migrations to an explicit destination node.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Honggyu Kim <honggyu.kim@sk.com>
Signed-off-by: Jiahui Zhang <jiahuitry@outlook.com>
Reviewed-by: SJ Park <sj@kernel.org>
Signed-off-by: SJ Park <sj@kernel.org>
---
Changes from v2
- v2: https://lore.kernel.org/ <MN2PR02MB665479119535A1235D69F125B5F92@MN2PR02MB6654.namprd02.prod.outlook.com>
- Collect R-b: from SJ.
- Rebase to the latest mm-new.
Changes since v1:
- Use the mm/damon/ops-common subject prefix.
- Describe the observed misleading migration accounting and how strict
target-node allocation resolves it.
- Use the formal author name.
- No functional/code change from v1
- Link to v1: https://lore.kernel.org/damon/BY5PR02MB6642F4D1A8BA92BFF3A034B4B5FF2@BY5PR02MB6642.namprd02
mm/damon/ops-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
index d7d7f100389b0..e59f77eca83b2 100644
--- a/mm/damon/ops-common.c
+++ b/mm/damon/ops-common.c
@@ -312,7 +312,7 @@ static unsigned int __damon_migrate_folio_list(
* instead of migrated.
*/
.gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
- __GFP_NOMEMALLOC | GFP_NOWAIT,
+ __GFP_NOMEMALLOC | GFP_NOWAIT | __GFP_THISNODE,
.nid = target_nid,
};
base-commit: 86e9ddaf85a3e872e81e1946ed410ef7f5341e16
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes
2026-07-21 13:56 [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes SJ Park
@ 2026-07-21 14:07 ` sashiko-bot
2026-07-21 14:18 ` SJ Park
0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-07-21 14:07 UTC (permalink / raw)
To: SJ Park; +Cc: damon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] alloc_migration_target() overrides non-blocking gfp flags for large folios, causing kdamond to stall in synchronous direct reclaim.
--
--- Patch [1]: [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes ---
commit 18e8e5ad17abc759ddf7302875cde768864ba912
Author: Jiahui Zhang <jiahuitry@outlook.com>
mm/damon/ops-common: prevent migration fallback to non-target nodes
This commit modifies DAMON's migration target allocation to use __GFP_THISNODE.
This prevents the allocator from silently falling back to other nodes when the
target node is full, which previously caused misleading migration statistics.
> diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
> index d7d7f100389b0..e59f77eca83b2 100644
> --- a/mm/damon/ops-common.c
> +++ b/mm/damon/ops-common.c
> @@ -312,7 +312,7 @@ static unsigned int __damon_migrate_folio_list(
> * instead of migrated.
> */
> .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
> - __GFP_NOMEMALLOC | GFP_NOWAIT,
> + __GFP_NOMEMALLOC | GFP_NOWAIT | __GFP_THISNODE,
[Severity: High]
This is a pre-existing issue, but does adding __GFP_THISNODE here cause kdamond
to unexpectedly stall in synchronous direct reclaim when migrating large folios?
When migrate_pages() is called, it uses alloc_migration_target() in
mm/migrate.c. For large folios, alloc_migration_target() unconditionally
overrides the non-blocking GFP flags requested by DAMON:
mm/migrate.c:alloc_migration_target() {
...
if (folio_test_large(src)) {
/*
* clear __GFP_RECLAIM to make the migration callback
* consistent with regular THP allocations.
*/
gfp_mask &= ~__GFP_RECLAIM;
gfp_mask |= GFP_TRANSHUGE;
order = folio_order(src);
}
...
}
Because GFP_TRANSHUGE includes __GFP_DIRECT_RECLAIM, the allocation can block.
Previously, without __GFP_THISNODE, the allocator could fall back to another
node. By enforcing __GFP_THISNODE on a full target node, this forced direct
reclaim will trigger, stalling the kdamond thread and preventing kswapd wakeups.
Could alloc_migration_target() be updated to respect the caller's intent to
not block?
> .nid = target_nid,
> };
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721135607.251869-1-sj@kernel.org?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes
2026-07-21 14:07 ` sashiko-bot
@ 2026-07-21 14:18 ` SJ Park
0 siblings, 0 replies; 3+ messages in thread
From: SJ Park @ 2026-07-21 14:18 UTC (permalink / raw)
To: sashiko-bot; +Cc: SJ Park, damon
On Tue, 21 Jul 2026 14:07:16 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] alloc_migration_target() overrides non-blocking gfp flags for large folios, causing kdamond to stall in synchronous direct reclaim.
> --
>
> --- Patch [1]: [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes ---
> commit 18e8e5ad17abc759ddf7302875cde768864ba912
> Author: Jiahui Zhang <jiahuitry@outlook.com>
>
> mm/damon/ops-common: prevent migration fallback to non-target nodes
>
> This commit modifies DAMON's migration target allocation to use __GFP_THISNODE.
> This prevents the allocator from silently falling back to other nodes when the
> target node is full, which previously caused misleading migration statistics.
>
> > diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
> > index d7d7f100389b0..e59f77eca83b2 100644
> > --- a/mm/damon/ops-common.c
> > +++ b/mm/damon/ops-common.c
> > @@ -312,7 +312,7 @@ static unsigned int __damon_migrate_folio_list(
> > * instead of migrated.
> > */
> > .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
> > - __GFP_NOMEMALLOC | GFP_NOWAIT,
> > + __GFP_NOMEMALLOC | GFP_NOWAIT | __GFP_THISNODE,
>
> [Severity: High]
> This is a pre-existing issue, but does adding __GFP_THISNODE here cause kdamond
> to unexpectedly stall in synchronous direct reclaim when migrating large folios?
>
> When migrate_pages() is called, it uses alloc_migration_target() in
> mm/migrate.c. For large folios, alloc_migration_target() unconditionally
> overrides the non-blocking GFP flags requested by DAMON:
>
> mm/migrate.c:alloc_migration_target() {
> ...
> if (folio_test_large(src)) {
> /*
> * clear __GFP_RECLAIM to make the migration callback
> * consistent with regular THP allocations.
> */
> gfp_mask &= ~__GFP_RECLAIM;
> gfp_mask |= GFP_TRANSHUGE;
> order = folio_order(src);
> }
> ...
> }
>
> Because GFP_TRANSHUGE includes __GFP_DIRECT_RECLAIM, the allocation can block.
> Previously, without __GFP_THISNODE, the allocator could fall back to another
> node. By enforcing __GFP_THISNODE on a full target node, this forced direct
> reclaim will trigger, stalling the kdamond thread and preventing kswapd wakeups.
>
> Could alloc_migration_target() be updated to respect the caller's intent to
> not block?
The new behavior looks fine for now. DAMON-based memory tiering is usually for
proactive use, so no much memory pressure is expected. We migth need to
revisit this later for making it more cleaner, though. Maybe it should be more
similar to that of do_move_pages_to_node().
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-21 14:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 13:56 [PATCH v3] mm/damon/ops-common: prevent migration fallback to non-target nodes SJ Park
2026-07-21 14:07 ` sashiko-bot
2026-07-21 14:18 ` SJ Park
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox