]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon: move migration helpers from paddr to ops-common
authorBijan Tabatabai <bijantabatab@micron.com>
Wed, 9 Jul 2025 00:59:38 +0000 (19:59 -0500)
committerAndrew Morton <akpm@linux-foundation.org>
Sun, 20 Jul 2025 01:59:49 +0000 (18:59 -0700)
This patch moves the damon_pa_migrate_pages function along with its
corresponding helper functions from paddr to ops-common.  The function
prefix of "damon_pa_" was also changed to just "damon_" accordingly.

This patch will allow page migration to be available to vaddr schemes as
well as paddr schemes.

Link: https://lkml.kernel.org/r/20250709005952.17776-9-bijan311@gmail.com
Co-developed-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
Signed-off-by: Ravi Shankar Jonnalagadda <ravis.opensrc@micron.com>
Signed-off-by: Bijan Tabatabai <bijantabatab@micron.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/ops-common.c
mm/damon/ops-common.h
mm/damon/paddr.c

index b43620fee6bb21436b63998b70c8742dbc252217..918158ef3d99eefe4460fa9ac17a37e7bbcda0f1 100644 (file)
@@ -5,6 +5,7 @@
  * Author: SeongJae Park <sj@kernel.org>
  */
 
+#include <linux/migrate.h>
 #include <linux/mmu_notifier.h>
 #include <linux/page_idle.h>
 #include <linux/pagemap.h>
@@ -12,6 +13,7 @@
 #include <linux/swap.h>
 #include <linux/swapops.h>
 
+#include "../internal.h"
 #include "ops-common.h"
 
 /*
@@ -138,3 +140,121 @@ int damon_cold_score(struct damon_ctx *c, struct damon_region *r,
        /* Return coldness of the region */
        return DAMOS_MAX_SCORE - hotness;
 }
+
+static unsigned int __damon_migrate_folio_list(
+               struct list_head *migrate_folios, struct pglist_data *pgdat,
+               int target_nid)
+{
+       unsigned int nr_succeeded = 0;
+       struct migration_target_control mtc = {
+               /*
+                * Allocate from 'node', or fail quickly and quietly.
+                * When this happens, 'page' will likely just be discarded
+                * instead of migrated.
+                */
+               .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
+                       __GFP_NOWARN | __GFP_NOMEMALLOC | GFP_NOWAIT,
+               .nid = target_nid,
+       };
+
+       if (pgdat->node_id == target_nid || target_nid == NUMA_NO_NODE)
+               return 0;
+
+       if (list_empty(migrate_folios))
+               return 0;
+
+       /* Migration ignores all cpuset and mempolicy settings */
+       migrate_pages(migrate_folios, alloc_migration_target, NULL,
+                     (unsigned long)&mtc, MIGRATE_ASYNC, MR_DAMON,
+                     &nr_succeeded);
+
+       return nr_succeeded;
+}
+
+static unsigned int damon_migrate_folio_list(struct list_head *folio_list,
+                                               struct pglist_data *pgdat,
+                                               int target_nid)
+{
+       unsigned int nr_migrated = 0;
+       struct folio *folio;
+       LIST_HEAD(ret_folios);
+       LIST_HEAD(migrate_folios);
+
+       while (!list_empty(folio_list)) {
+               struct folio *folio;
+
+               cond_resched();
+
+               folio = lru_to_folio(folio_list);
+               list_del(&folio->lru);
+
+               if (!folio_trylock(folio))
+                       goto keep;
+
+               /* Relocate its contents to another node. */
+               list_add(&folio->lru, &migrate_folios);
+               folio_unlock(folio);
+               continue;
+keep:
+               list_add(&folio->lru, &ret_folios);
+       }
+       /* 'folio_list' is always empty here */
+
+       /* Migrate folios selected for migration */
+       nr_migrated += __damon_migrate_folio_list(
+                       &migrate_folios, pgdat, target_nid);
+       /*
+        * Folios that could not be migrated are still in @migrate_folios.  Add
+        * those back on @folio_list
+        */
+       if (!list_empty(&migrate_folios))
+               list_splice_init(&migrate_folios, folio_list);
+
+       try_to_unmap_flush();
+
+       list_splice(&ret_folios, folio_list);
+
+       while (!list_empty(folio_list)) {
+               folio = lru_to_folio(folio_list);
+               list_del(&folio->lru);
+               folio_putback_lru(folio);
+       }
+
+       return nr_migrated;
+}
+
+unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid)
+{
+       int nid;
+       unsigned long nr_migrated = 0;
+       LIST_HEAD(node_folio_list);
+       unsigned int noreclaim_flag;
+
+       if (list_empty(folio_list))
+               return nr_migrated;
+
+       noreclaim_flag = memalloc_noreclaim_save();
+
+       nid = folio_nid(lru_to_folio(folio_list));
+       do {
+               struct folio *folio = lru_to_folio(folio_list);
+
+               if (nid == folio_nid(folio)) {
+                       list_move(&folio->lru, &node_folio_list);
+                       continue;
+               }
+
+               nr_migrated += damon_migrate_folio_list(&node_folio_list,
+                                                          NODE_DATA(nid),
+                                                          target_nid);
+               nid = folio_nid(lru_to_folio(folio_list));
+       } while (!list_empty(folio_list));
+
+       nr_migrated += damon_migrate_folio_list(&node_folio_list,
+                                                  NODE_DATA(nid),
+                                                  target_nid);
+
+       memalloc_noreclaim_restore(noreclaim_flag);
+
+       return nr_migrated;
+}
index cc9f5da9c012753f0fa2f3e708d498ee877ba33d..54209a7e70e67bc0d8163a8c8424e9b58374a9f3 100644 (file)
@@ -16,3 +16,5 @@ int damon_cold_score(struct damon_ctx *c, struct damon_region *r,
                        struct damos *s);
 int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
                        struct damos *s);
+
+unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid);
index fcab148e68652434b2ae899dd417109786507f7e..48e3e6fed63638c5aa43d463e825719751500d0a 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/rmap.h>
 #include <linux/swap.h>
 #include <linux/memory-tiers.h>
-#include <linux/migrate.h>
 #include <linux/mm_inline.h>
 
 #include "../internal.h"
@@ -381,125 +380,6 @@ static unsigned long damon_pa_deactivate_pages(struct damon_region *r,
                        sz_filter_passed);
 }
 
-static unsigned int __damon_pa_migrate_folio_list(
-               struct list_head *migrate_folios, struct pglist_data *pgdat,
-               int target_nid)
-{
-       unsigned int nr_succeeded = 0;
-       struct migration_target_control mtc = {
-               /*
-                * Allocate from 'node', or fail quickly and quietly.
-                * When this happens, 'page' will likely just be discarded
-                * instead of migrated.
-                */
-               .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) |
-                       __GFP_NOWARN | __GFP_NOMEMALLOC | GFP_NOWAIT,
-               .nid = target_nid,
-       };
-
-       if (pgdat->node_id == target_nid || target_nid == NUMA_NO_NODE)
-               return 0;
-
-       if (list_empty(migrate_folios))
-               return 0;
-
-       /* Migration ignores all cpuset and mempolicy settings */
-       migrate_pages(migrate_folios, alloc_migration_target, NULL,
-                     (unsigned long)&mtc, MIGRATE_ASYNC, MR_DAMON,
-                     &nr_succeeded);
-
-       return nr_succeeded;
-}
-
-static unsigned int damon_pa_migrate_folio_list(struct list_head *folio_list,
-                                               struct pglist_data *pgdat,
-                                               int target_nid)
-{
-       unsigned int nr_migrated = 0;
-       struct folio *folio;
-       LIST_HEAD(ret_folios);
-       LIST_HEAD(migrate_folios);
-
-       while (!list_empty(folio_list)) {
-               struct folio *folio;
-
-               cond_resched();
-
-               folio = lru_to_folio(folio_list);
-               list_del(&folio->lru);
-
-               if (!folio_trylock(folio))
-                       goto keep;
-
-               /* Relocate its contents to another node. */
-               list_add(&folio->lru, &migrate_folios);
-               folio_unlock(folio);
-               continue;
-keep:
-               list_add(&folio->lru, &ret_folios);
-       }
-       /* 'folio_list' is always empty here */
-
-       /* Migrate folios selected for migration */
-       nr_migrated += __damon_pa_migrate_folio_list(
-                       &migrate_folios, pgdat, target_nid);
-       /*
-        * Folios that could not be migrated are still in @migrate_folios.  Add
-        * those back on @folio_list
-        */
-       if (!list_empty(&migrate_folios))
-               list_splice_init(&migrate_folios, folio_list);
-
-       try_to_unmap_flush();
-
-       list_splice(&ret_folios, folio_list);
-
-       while (!list_empty(folio_list)) {
-               folio = lru_to_folio(folio_list);
-               list_del(&folio->lru);
-               folio_putback_lru(folio);
-       }
-
-       return nr_migrated;
-}
-
-static unsigned long damon_pa_migrate_pages(struct list_head *folio_list,
-                                           int target_nid)
-{
-       int nid;
-       unsigned long nr_migrated = 0;
-       LIST_HEAD(node_folio_list);
-       unsigned int noreclaim_flag;
-
-       if (list_empty(folio_list))
-               return nr_migrated;
-
-       noreclaim_flag = memalloc_noreclaim_save();
-
-       nid = folio_nid(lru_to_folio(folio_list));
-       do {
-               struct folio *folio = lru_to_folio(folio_list);
-
-               if (nid == folio_nid(folio)) {
-                       list_move(&folio->lru, &node_folio_list);
-                       continue;
-               }
-
-               nr_migrated += damon_pa_migrate_folio_list(&node_folio_list,
-                                                          NODE_DATA(nid),
-                                                          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),
-                                                  target_nid);
-
-       memalloc_noreclaim_restore(noreclaim_flag);
-
-       return nr_migrated;
-}
-
 static unsigned long damon_pa_migrate(struct damon_region *r, struct damos *s,
                unsigned long *sz_filter_passed)
 {
@@ -527,7 +407,7 @@ put_folio:
                addr += folio_size(folio);
                folio_put(folio);
        }
-       applied = damon_pa_migrate_pages(&folio_list, s->target_nid);
+       applied = damon_migrate_pages(&folio_list, s->target_nid);
        cond_resched();
        s->last_applied = folio;
        return applied * PAGE_SIZE;