From: Hyeongtak Ji <hyeongtak.ji@xxxxxx> This patch changes DAMOS_PROMOTE and DAMOS_DEMOTE to use target_nid of sysfs as the destination NUMA node of migration. This has been tested on qemu as follows: $ cd /sys/kernel/mm/damon/admin/kdamonds/<N> $ cat contexts/<N>/schemes/<N>/action promote $ echo 1 > contexts/<N>/schemes/<N>/target_nid $ echo commit > state $ numactl -p 2 ./hot_cold 500M 600M & $ numastat -c -p hot_cold Per-node process memory usage (in MBs) PID Node 0 Node 1 Node 2 Total -------------- ------ ------ ------ ----- 701 (hot_cold) 0 501 601 1101 Signed-off-by: Hyeongtak Ji <hyeongtak.ji@xxxxxx> Signed-off-by: Honggyu Kim <honggyu.kim@xxxxxx> --- mm/damon/paddr.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c index 37a7b34a36dd..5e057a69464f 100644 --- a/mm/damon/paddr.c +++ b/mm/damon/paddr.c @@ -240,9 +240,9 @@ enum migration_mode { */ static unsigned int migrate_folio_list(struct list_head *migrate_folios, struct pglist_data *pgdat, - enum migration_mode mm) + enum migration_mode mm, + int target_nid) { - int target_nid; unsigned int nr_succeeded; nodemask_t allowed_mask; int reason; @@ -250,12 +250,14 @@ static unsigned int migrate_folio_list(struct list_head *migrate_folios, switch (mm) { case MIG_PROMOTE: - target_nid = next_promotion_node(pgdat->node_id); + if (target_nid == NUMA_NO_NODE) + target_nid = next_promotion_node(pgdat->node_id); reason = MR_PROMOTION; vm_event = PGPROMOTE; break; case MIG_DEMOTE: - target_nid = next_demotion_node(pgdat->node_id); + if (target_nid == NUMA_NO_NODE) + target_nid = next_demotion_node(pgdat->node_id); reason = MR_DEMOTION; vm_event = PGDEMOTE_DIRECT; break; @@ -358,7 +360,8 @@ static enum folio_references folio_check_references(struct folio *folio) */ static unsigned int damon_pa_migrate_folio_list(struct list_head *folio_list, struct pglist_data *pgdat, - enum migration_mode mm) + enum migration_mode mm, + int target_nid) { unsigned int nr_migrated = 0; struct folio *folio; @@ -399,7 +402,7 @@ static unsigned int damon_pa_migrate_folio_list(struct list_head *folio_list, /* 'folio_list' is always empty here */ /* Migrate folios selected for migration */ - nr_migrated += migrate_folio_list(&migrate_folios, pgdat, mm); + nr_migrated += migrate_folio_list(&migrate_folios, pgdat, mm, target_nid); /* Folios that could not be migrated are still in @migrate_folios */ if (!list_empty(&migrate_folios)) { /* Folios which weren't migrated go back on @folio_list */ @@ -426,7 +429,8 @@ static unsigned int damon_pa_migrate_folio_list(struct list_head *folio_list, * common function for both cases. */ static unsigned long damon_pa_migrate_pages(struct list_head *folio_list, - enum migration_mode mm) + enum migration_mode mm, + int target_nid) { int nid; unsigned int nr_migrated = 0; @@ -449,12 +453,14 @@ static unsigned long damon_pa_migrate_pages(struct list_head *folio_list, } nr_migrated += damon_pa_migrate_folio_list(&node_folio_list, - NODE_DATA(nid), mm); + NODE_DATA(nid), mm, + target_nid); nid = folio_nid(lru_to_folio(folio_list)); } while (!list_empty(folio_list)); nr_migrated += damon_pa_migrate_folio_list(&node_folio_list, - NODE_DATA(nid), mm); + NODE_DATA(nid), mm, + target_nid); memalloc_noreclaim_restore(noreclaim_flag); @@ -499,7 +505,8 @@ static unsigned long damon_pa_migrate(struct damon_region *r, struct damos *s, break; case MIG_PROMOTE: case MIG_DEMOTE: - applied = damon_pa_migrate_pages(&folio_list, mm); + applied = damon_pa_migrate_pages(&folio_list, mm, + s->target_nid); break; default: /* Unexpected migration mode. */ -- 2.34.1