Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Shivank Garg <shivankg@amd.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>, Zi Yan <ziy@nvidia.com>,
	Matthew Brost <matthew.brost@intel.com>,
	Joshua Hahn <joshua.hahnjy@gmail.com>,
	Rakie Kim <rakie.kim@sk.com>, Byungchul Park <byungchul@sk.com>,
	Gregory Price <gourry@gourry.net>,
	Ying Huang <ying.huang@linux.alibaba.com>,
	"Alistair Popple" <apopple@nvidia.com>,
	Vlastimil Babka <vbabka@kernel.org>,
	"Suren Baghdasaryan" <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	"Brendan Jackman" <brendan.jackman@linux.dev>,
	Johannes Weiner <hannes@cmpxchg.org>, "SJ Park" <sj@kernel.org>,
	Jason Gunthorpe <jgg@ziepe.ca>,
	John Hubbard <jhubbard@nvidia.com>, Peter Xu <peterx@redhat.com>,
	Miaohe Lin <linmiaohe@huawei.com>,
	Naoya Horiguchi <nao.horiguchi@gmail.com>,
	"Oscar Salvador" <osalvador@suse.de>,
	Kairui Song <kasong@tencent.com>, Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Barry Song <baohua@kernel.org>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	Lorenzo Stoakes <ljs@kernel.org>,
	"Matthew Wilcox (Oracle)" <willy@infradead.org>,
	Jan Kara <jack@suse.cz>, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	Benjamin LaHaise <bcrl@kvack.org>, Chris Mason <clm@fb.com>,
	David Sterba <dsterba@suse.com>,
	Muchun Song <muchun.song@linux.dev>,
	Dave Kleikamp <shaggy@kernel.org>,
	Trond Myklebust <trondmy@kernel.org>,
	Anna Schumaker <anna@kernel.org>, Mike Rapoport <rppt@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Bharata B Rao <bharata@amd.com>,
	David Rientjes <rientjes@google.com>,
	"Yiannis Nikolakopoulos" <yiannis@zptcorp.com>
Cc: <linux-mm@kvack.org>, <linux-kernel@vger.kernel.org>,
	<damon@lists.linux.dev>, <linux-cxl@vger.kernel.org>,
	<linux-fsdevel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-aio@kvack.org>, <linux-btrfs@vger.kernel.org>,
	<jfs-discussion@lists.sourceforge.net>,
	<linux-nfs@vger.kernel.org>, <kvm@vger.kernel.org>,
	Shivank Garg <shivankg@amd.com>
Subject: [PATCH RFC 09/11] mm/migrate: thread migration policy through a control struct
Date: Wed, 2 Sep 2026 10:52:23 +0000	[thread overview]
Message-ID: <20260902-migrate-refactor-shivank-v1-9-9dcca87669c4@amd.com> (raw)
In-Reply-To: <20260902-migrate-refactor-shivank-v1-0-9dcca87669c4@amd.com>

Migration mode and reason describe one migration invocation, but are passed
separately through every migration engine and phase. Adding more policy
would require another parameter through the same call graph or overloading
migrate_mode with unrelated information.

Add struct migrate_control, initialize it on the migrate_pages() stack, and
pass it as const through the internal migration helpers. This provides one
place for additional policy, such as copy-cache hints.

Use a derived control for asynchronous pre-passes and split-folio retries.
Keep the public migration and filesystem callback interfaces unchanged in
this patch and will be handled separately in upcoming patch.

No functional change intended.

Signed-off-by: Shivank Garg <shivankg@amd.com>
---
 include/linux/migrate_mode.h |  14 +++++
 mm/migrate.c                 | 144 ++++++++++++++++++++++---------------------
 2 files changed, 88 insertions(+), 70 deletions(-)

diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h
index 05102d4d2490..388acddfdae8 100644
--- a/include/linux/migrate_mode.h
+++ b/include/linux/migrate_mode.h
@@ -29,4 +29,18 @@ enum migrate_reason {
 	MR_TYPES
 };
 
+/**
+ * struct migrate_control - Policy for one migration invocation
+ * @mode: Blocking discipline for migration operations
+ * @reason: Reason the migration was requested
+ *
+ * Per-folio completion state does not belong here.  Callers keep this
+ * structure on the stack; migration must not allocate it under memory
+ * pressure.
+ */
+struct migrate_control {
+	enum migrate_mode mode;
+	enum migrate_reason reason;
+};
+
 #endif		/* MIGRATE_MODE_H_INCLUDED */
diff --git a/mm/migrate.c b/mm/migrate.c
index 8914358cc434..e4bc7122076e 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1103,7 +1103,7 @@ static int fallback_migrate_folio(struct address_space *mapping,
  *     0 - success
  */
 static int move_to_new_folio(struct folio *dst, struct folio *src,
-				enum migrate_mode mode)
+		const struct migrate_control *ctl)
 {
 	struct address_space *mapping = folio_mapping(src);
 	int rc = -EAGAIN;
@@ -1112,7 +1112,7 @@ static int move_to_new_folio(struct folio *dst, struct folio *src,
 	VM_BUG_ON_FOLIO(!folio_test_locked(dst), dst);
 
 	if (!mapping)
-		rc = migrate_folio(mapping, dst, src, mode);
+		rc = migrate_folio(mapping, dst, src, ctl->mode);
 	else if (mapping_inaccessible(mapping))
 		rc = -EOPNOTSUPP;
 	else if (mapping->a_ops->migrate_folio)
@@ -1123,10 +1123,9 @@ static int move_to_new_folio(struct folio *dst, struct folio *src,
 		 * migrate_folio callback. This is the most common path
 		 * for page migration.
 		 */
-		rc = mapping->a_ops->migrate_folio(mapping, dst, src,
-							mode);
+		rc = mapping->a_ops->migrate_folio(mapping, dst, src, ctl->mode);
 	else
-		rc = fallback_migrate_folio(mapping, dst, src, mode);
+		rc = fallback_migrate_folio(mapping, dst, src, ctl->mode);
 
 	if (!rc) {
 		/*
@@ -1198,13 +1197,13 @@ static void migrate_folio_undo_dst(struct folio *dst, bool locked,
 
 /* Cleanup src folio upon migration success */
 static void migrate_folio_done(struct folio *src,
-			       enum migrate_reason reason)
+		const struct migrate_control *ctl)
 {
-	if (reason != MR_DEMOTION)
+	if (ctl->reason != MR_DEMOTION)
 		mod_node_page_state(folio_pgdat(src), NR_ISOLATED_ANON +
 				    folio_is_file_lru(src), -folio_nr_pages(src));
 
-	if (reason != MR_MEMORY_FAILURE)
+	if (ctl->reason != MR_MEMORY_FAILURE)
 		/* We release the page in page_handle_poison. */
 		folio_put(src);
 }
@@ -1212,8 +1211,8 @@ static void migrate_folio_done(struct folio *src,
 /* Obtain the lock on page, remove all ptes. */
 static int migrate_folio_unmap(new_folio_t get_new_folio,
 		free_folio_t put_new_folio, unsigned long private,
-		struct folio *src, struct folio **dstp, enum migrate_mode mode,
-		struct list_head *ret)
+		struct folio *src, struct folio **dstp,
+		const struct migrate_control *ctl, struct list_head *ret)
 {
 	struct folio *dst;
 	int rc = -EAGAIN;
@@ -1230,7 +1229,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 	dst->migrate_info = 0;
 
 	if (!folio_trylock(src)) {
-		if (mode == MIGRATE_ASYNC)
+		if (ctl->mode == MIGRATE_ASYNC)
 			goto out;
 
 		/*
@@ -1254,7 +1253,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 		 * inserting a page into the page table), but it's not
 		 * worth waiting for I/O.
 		 */
-		if (mode == MIGRATE_SYNC_LIGHT && !folio_test_uptodate(src))
+		if (ctl->mode == MIGRATE_SYNC_LIGHT && !folio_test_uptodate(src))
 			goto out;
 
 		folio_lock(src);
@@ -1270,7 +1269,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 		 * the retry loop is too short and in the sync-light case,
 		 * the overhead of stalling is too much
 		 */
-		switch (mode) {
+		switch (ctl->mode) {
 		case MIGRATE_SYNC:
 			break;
 		default:
@@ -1330,7 +1329,8 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 		/* Establish migration ptes */
 		VM_BUG_ON_FOLIO(folio_test_anon(src) &&
 			       !folio_test_ksm(src) && !anon_vma, src);
-		try_to_migrate(src, mode == MIGRATE_ASYNC ? TTU_BATCH_FLUSH : 0);
+		try_to_migrate(src, ctl->mode == MIGRATE_ASYNC ?
+			TTU_BATCH_FLUSH : 0);
 		old_folio_state |= FOLIO_WAS_MAPPED;
 	}
 
@@ -1356,9 +1356,8 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 
 /* Migrate the folio to the newly allocated folio in dst. */
 static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
-			      struct folio *src, struct folio *dst,
-			      enum migrate_mode mode, enum migrate_reason reason,
-			      struct list_head *ret)
+		struct folio *src, struct folio *dst,
+		const struct migrate_control *ctl, struct list_head *ret)
 {
 	int rc;
 	int old_folio_state = 0;
@@ -1377,7 +1376,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 		src_partially_mapped = folio_test_partially_mapped(src);
 	}
 
-	rc = move_to_new_folio(dst, src, mode);
+	rc = move_to_new_folio(dst, src, ctl);
 	if (rc)
 		goto out;
 
@@ -1407,7 +1406,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 		remove_migration_ptes(src, dst, 0);
 
 	folio_unlock(dst);
-	folio_set_owner_migrate_reason(dst, reason);
+	folio_set_owner_migrate_reason(dst, ctl->reason);
 	/*
 	 * If migration is successful, decrease refcount of dst,
 	 * which will not free the page because new page owner increased
@@ -1424,7 +1423,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 	if (anon_vma)
 		put_anon_vma(anon_vma);
 	folio_unlock(src);
-	migrate_folio_done(src, reason);
+	migrate_folio_done(src, ctl);
 
 	return rc;
 out:
@@ -1466,8 +1465,8 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
  */
 static int unmap_and_move_hugetlb_folio(new_folio_t get_new_folio,
 		free_folio_t put_new_folio, unsigned long private,
-		struct folio *src, int force, enum migrate_mode mode,
-		enum migrate_reason reason, struct list_head *ret)
+		struct folio *src, int force, const struct migrate_control *ctl,
+		struct list_head *ret)
 {
 	struct folio *dst;
 	int rc = -EAGAIN;
@@ -1489,7 +1488,7 @@ static int unmap_and_move_hugetlb_folio(new_folio_t get_new_folio,
 	if (!folio_trylock(src)) {
 		if (!force)
 			goto out;
-		switch (mode) {
+		switch (ctl->mode) {
 		case MIGRATE_SYNC:
 			break;
 		default:
@@ -1534,7 +1533,7 @@ static int unmap_and_move_hugetlb_folio(new_folio_t get_new_folio,
 	}
 
 	if (!folio_mapped(src))
-		rc = move_to_new_folio(dst, src, mode);
+		rc = move_to_new_folio(dst, src, ctl);
 
 	if (was_mapped)
 		remove_migration_ptes(src, !rc ? dst : src, ttu);
@@ -1550,7 +1549,7 @@ static int unmap_and_move_hugetlb_folio(new_folio_t get_new_folio,
 		put_anon_vma(anon_vma);
 
 	if (!rc) {
-		move_hugetlb_state(src, dst, reason);
+		move_hugetlb_state(src, dst, ctl->reason);
 		put_new_folio = NULL;
 	}
 
@@ -1625,7 +1624,7 @@ struct migrate_pages_stats {
  */
 static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
 			    free_folio_t put_new_folio, unsigned long private,
-			    enum migrate_mode mode, enum migrate_reason reason,
+			    const struct migrate_control *ctl,
 			    struct migrate_pages_stats *stats,
 			    struct list_head *ret_folios)
 {
@@ -1666,8 +1665,8 @@ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
 
 			rc = unmap_and_move_hugetlb_folio(get_new_folio,
 							  put_new_folio, private,
-							  folio, pass > 2, mode,
-							  reason, ret_folios);
+							  folio, pass > 2, ctl,
+							  ret_folios);
 			/*
 			 * The rules are:
 			 *	0: hugetlb folio will be put back
@@ -1721,7 +1720,7 @@ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
 static void migrate_folios_move(struct list_head *src_folios,
 		struct list_head *dst_folios,
 		free_folio_t put_new_folio, unsigned long private,
-		enum migrate_mode mode, enum migrate_reason reason,
+		const struct migrate_control *ctl,
 		struct list_head *ret_folios,
 		struct migrate_pages_stats *stats, int nr_pass,
 		int *nr_failed)
@@ -1748,7 +1747,7 @@ static void migrate_folios_move(struct list_head *src_folios,
 			cond_resched();
 
 			rc = migrate_folio_move(put_new_folio, private,
-					folio, dst, mode, reason, ret_folios);
+					folio, dst, ctl, ret_folios);
 			/*
 			 * The rules are:
 			 *	0: folio will be freed
@@ -1811,8 +1810,8 @@ static void migrate_folios_undo(struct list_head *src_folios,
  */
 static int move_movable_ops_page(struct folio *src,
 		new_folio_t get_new_folio, free_folio_t put_new_folio,
-		unsigned long private, enum migrate_mode mode,
-		enum migrate_reason reason, struct list_head *ret_folios)
+		unsigned long private, const struct migrate_control *ctl,
+		struct list_head *ret_folios)
 {
 	struct folio *dst;
 	int rc = -EAGAIN;
@@ -1822,7 +1821,7 @@ static int move_movable_ops_page(struct folio *src,
 		return -ENOMEM;
 
 	if (!folio_trylock(src)) {
-		if (mode == MIGRATE_ASYNC)
+		if (ctl->mode == MIGRATE_ASYNC)
 			goto out_put_dst;
 		if (current->flags & PF_MEMALLOC)
 			goto out_put_dst;
@@ -1832,19 +1831,19 @@ static int move_movable_ops_page(struct folio *src,
 	if (unlikely(!folio_trylock(dst)))
 		goto out_unlock_src;
 
-	rc = migrate_movable_ops_page(&dst->page, &src->page, mode);
+	rc = migrate_movable_ops_page(&dst->page, &src->page, ctl->mode);
 	folio_unlock(dst);
 	if (rc)
 		goto out_unlock_src;
 
-	folio_set_owner_migrate_reason(dst, reason);
+	folio_set_owner_migrate_reason(dst, ctl->reason);
 	/* Drop migration's reference after transferring ownership to dst. */
 	folio_put(dst);
 
 	list_del(&src->lru);
 	folio_unlock(src);
 
-	if (reason != MR_MEMORY_FAILURE)
+	if (ctl->reason != MR_MEMORY_FAILURE)
 		folio_put(src);
 
 	return 0;
@@ -1872,8 +1871,8 @@ static int move_movable_ops_page(struct folio *src,
  */
 static int migrate_movable_ops_pages(struct list_head *from,
 		new_folio_t get_new_folio, free_folio_t put_new_folio,
-		unsigned long private, enum migrate_mode mode,
-		enum migrate_reason reason, struct migrate_pages_stats *stats,
+		unsigned long private, const struct migrate_control *ctl,
+		struct migrate_pages_stats *stats,
 		struct list_head *ret_folios)
 {
 	int retry = 1;
@@ -1895,7 +1894,7 @@ static int migrate_movable_ops_pages(struct list_head *from,
 
 			rc = move_movable_ops_page(folio, get_new_folio,
 						   put_new_folio, private,
-						   mode, reason, ret_folios);
+						   ctl, ret_folios);
 			switch (rc) {
 			case -ENOMEM:
 				/* Count this page and those awaiting retry. */
@@ -1933,17 +1932,17 @@ static int migrate_movable_ops_pages(struct list_head *from,
  * unmap phase.
  */
 static int migrate_folio_split_on_alloc_fail(struct folio *folio,
-		struct list_head *split_folios, enum migrate_mode mode,
-		enum migrate_reason reason, struct migrate_pages_stats *stats)
+		struct list_head *split_folios, const struct migrate_control *ctl,
+		struct migrate_pages_stats *stats)
 {
 	bool is_thp = folio_test_pmd_mappable(folio);
 	int rc;
 
 	/* Large folio NUMA faulting doesn't split to retry. */
-	if (!folio_test_large(folio) || reason == MR_NUMA_MISPLACED)
+	if (!folio_test_large(folio) || ctl->reason == MR_NUMA_MISPLACED)
 		return -ENOMEM;
 
-	rc = try_split_folio(folio, split_folios, mode);
+	rc = try_split_folio(folio, split_folios, ctl->mode);
 	if (!rc) {
 		stats->nr_thp_split += is_thp;
 		stats->nr_split++;
@@ -1954,7 +1953,7 @@ static int migrate_folio_split_on_alloc_fail(struct folio *folio,
 	 * Try again to split large folio to mitigate the failure of longterm
 	 * pinning.
 	 */
-	if (reason == MR_LONGTERM_PIN && rc == -EAGAIN)
+	if (ctl->reason == MR_LONGTERM_PIN && rc == -EAGAIN)
 		return -EAGAIN;
 
 	return -ENOMEM;
@@ -1970,7 +1969,7 @@ static int migrate_folio_split_on_alloc_fail(struct folio *folio,
  */
 static int migrate_folios_unmap(struct list_head *from,
 		new_folio_t get_new_folio, free_folio_t put_new_folio,
-		unsigned long private, enum migrate_mode mode, enum migrate_reason reason,
+		unsigned long private, const struct migrate_control *ctl,
 		struct list_head *ret_folios, struct list_head *split_folios,
 		struct list_head *unmap_folios, struct list_head *dst_folios,
 		struct migrate_pages_stats *stats, int nr_pass, int *nr_failed)
@@ -2020,7 +2019,7 @@ static int migrate_folios_unmap(struct list_head *from,
 			if (nr_pages > 2 &&
 			   !list_empty(&folio->_deferred_list) &&
 			   folio_test_partially_mapped(folio)) {
-				if (!try_split_folio(folio, split_folios, mode)) {
+				if (!try_split_folio(folio, split_folios, ctl->mode)) {
 					*nr_failed += 1;
 					stats->nr_thp_failed += is_thp;
 					stats->nr_thp_split += is_thp;
@@ -2042,7 +2041,7 @@ static int migrate_folios_unmap(struct list_head *from,
 			if (!thp_migration_supported() && is_thp) {
 				*nr_failed += 1;
 				stats->nr_thp_failed++;
-				if (!try_split_folio(folio, split_folios, mode)) {
+				if (!try_split_folio(folio, split_folios, ctl->mode)) {
 					stats->nr_thp_split++;
 					stats->nr_split++;
 					continue;
@@ -2060,14 +2059,14 @@ static int migrate_folios_unmap(struct list_head *from,
 				folio_clear_active(folio);
 				folio_clear_unevictable(folio);
 				list_del(&folio->lru);
-				migrate_folio_done(folio, reason);
+				migrate_folio_done(folio, ctl);
 				stats->nr_succeeded += nr_pages;
 				stats->nr_thp_succeeded += is_thp;
 				continue;
 			}
 
 			rc = migrate_folio_unmap(get_new_folio, put_new_folio,
-					private, folio, &dst, mode, ret_folios);
+					private, folio, &dst, ctl, ret_folios);
 			/*
 			 * The rules are:
 			 *	0: folio will be put on unmap_folios list,
@@ -2086,7 +2085,7 @@ static int migrate_folios_unmap(struct list_head *from,
 				stats->nr_thp_failed += is_thp;
 
 				split_rc = migrate_folio_split_on_alloc_fail(folio,
-						split_folios, mode, reason, stats);
+						split_folios, ctl, stats);
 				if (!split_rc)
 					break;
 				/* Retry this folio in a later pass. */
@@ -2145,7 +2144,7 @@ static int migrate_folios_unmap(struct list_head *from,
  */
 static int migrate_folios_batch(struct list_head *from,
 		new_folio_t get_new_folio, free_folio_t put_new_folio,
-		unsigned long private, enum migrate_mode mode, enum migrate_reason reason,
+		unsigned long private, const struct migrate_control *ctl,
 		struct list_head *ret_folios, struct list_head *split_folios,
 		struct migrate_pages_stats *stats, int nr_pass)
 {
@@ -2154,11 +2153,11 @@ static int migrate_folios_batch(struct list_head *from,
 	LIST_HEAD(unmap_folios);
 	LIST_HEAD(dst_folios);
 
-	VM_WARN_ON_ONCE(mode != MIGRATE_ASYNC &&
+	VM_WARN_ON_ONCE(ctl->mode != MIGRATE_ASYNC &&
 			!list_empty(from) && !list_is_singular(from));
 
 	rc_saved = migrate_folios_unmap(from, get_new_folio, put_new_folio,
-			private, mode, reason, ret_folios, split_folios,
+			private, ctl, ret_folios, split_folios,
 			&unmap_folios, &dst_folios, stats, nr_pass,
 			&nr_failed);
 	if (rc_saved && list_empty(&unmap_folios)) {
@@ -2171,7 +2170,7 @@ static int migrate_folios_batch(struct list_head *from,
 
 	/* Move the unmapped folios */
 	migrate_folios_move(&unmap_folios, &dst_folios, put_new_folio, private,
-			mode, reason, ret_folios, stats, nr_pass, &nr_failed);
+			ctl, ret_folios, stats, nr_pass, &nr_failed);
 
 	rc = rc_saved ? : nr_failed;
 out:
@@ -2189,27 +2188,29 @@ static int migrate_folios_batch(struct list_head *from,
  */
 static int __migrate_lru_folios(struct list_head *from, new_folio_t get_new_folio,
 		free_folio_t put_new_folio, unsigned long private,
-		enum migrate_mode mode, enum migrate_reason reason,
-		struct list_head *ret_folios,
+		const struct migrate_control *ctl, struct list_head *ret_folios,
 		struct migrate_pages_stats *stats)
 {
 	int rc, nr_failed = 0;
 	LIST_HEAD(folios);
 	LIST_HEAD(split_folios);
 	struct migrate_pages_stats astats;
+	struct migrate_control async_ctl;
 
-	if (mode == MIGRATE_ASYNC) {
+	if (ctl->mode == MIGRATE_ASYNC) {
 		rc = migrate_folios_batch(from, get_new_folio, put_new_folio,
-				private, mode, reason, ret_folios,
+				private, ctl, ret_folios,
 				&split_folios, stats,
 				NR_MAX_MIGRATE_PAGES_RETRY);
 		goto out;
 	}
 
+	async_ctl = *ctl;
+	async_ctl.mode = MIGRATE_ASYNC;
 	memset(&astats, 0, sizeof(astats));
 	/* Try to migrate in batch with MIGRATE_ASYNC mode firstly */
 	rc = migrate_folios_batch(from, get_new_folio, put_new_folio, private,
-			MIGRATE_ASYNC, reason, &folios, &split_folios, &astats,
+			&async_ctl, &folios, &split_folios, &astats,
 			NR_MAX_MIGRATE_ASYNC_RETRY);
 	stats->nr_succeeded += astats.nr_succeeded;
 	stats->nr_thp_succeeded += astats.nr_thp_succeeded;
@@ -2236,8 +2237,7 @@ static int __migrate_lru_folios(struct list_head *from, new_folio_t get_new_foli
 	while (!list_empty(from)) {
 		list_move(from->next, &folios);
 		rc = migrate_folios_batch(&folios, get_new_folio, put_new_folio,
-				private, mode, reason, ret_folios,
-				&split_folios, stats,
+				private, ctl, ret_folios, &split_folios, stats,
 				NR_MAX_MIGRATE_SYNC_RETRY);
 		list_splice_tail_init(&folios, ret_folios);
 		if (rc < 0)
@@ -2255,7 +2255,7 @@ static int __migrate_lru_folios(struct list_head *from, new_folio_t get_new_foli
 		 * folio they came from was already counted as one failure.
 		 */
 		migrate_folios_batch(&split_folios, get_new_folio, put_new_folio,
-				private, MIGRATE_ASYNC, reason, ret_folios,
+				private, &async_ctl, ret_folios,
 				NULL, stats, 1);
 		list_splice_tail_init(&split_folios, ret_folios);
 	}
@@ -2270,7 +2270,7 @@ static int __migrate_lru_folios(struct list_head *from, new_folio_t get_new_foli
  */
 static int migrate_lru_folios(struct list_head *from, new_folio_t get_new_folio,
 		free_folio_t put_new_folio, unsigned long private,
-		enum migrate_mode mode, enum migrate_reason reason,
+		const struct migrate_control *ctl,
 		struct list_head *ret_folios,
 		struct migrate_pages_stats *stats)
 {
@@ -2292,7 +2292,7 @@ static int migrate_lru_folios(struct list_head *from, new_folio_t get_new_folio,
 			list_splice_init(from, &folios);
 
 		rc = __migrate_lru_folios(&folios, get_new_folio, put_new_folio,
-				private, mode, reason, ret_folios, stats);
+				private, ctl, ret_folios, stats);
 		list_splice_tail_init(&folios, ret_folios);
 		if (rc < 0)
 			return rc;
@@ -2335,18 +2335,22 @@ int migrate_pages(struct list_head *from, new_folio_t get_new_folio,
 	int rc, rc_gather;
 	LIST_HEAD(ret_folios);
 	struct migrate_pages_stats stats;
+	const struct migrate_control ctl = {
+		.mode = mode,
+		.reason = reason,
+	};
 
-	trace_mm_migrate_pages_start(mode, reason);
+	trace_mm_migrate_pages_start(ctl.mode, ctl.reason);
 
 	memset(&stats, 0, sizeof(stats));
 
 	rc_gather = migrate_hugetlbs(from, get_new_folio, put_new_folio, private,
-				     mode, reason, &stats, &ret_folios);
+				     &ctl, &stats, &ret_folios);
 	if (rc_gather < 0)
 		goto out;
 
 	rc = migrate_movable_ops_pages(from, get_new_folio, put_new_folio,
-				       private, mode, reason, &stats,
+				       private, &ctl, &stats,
 				       &ret_folios);
 	if (rc < 0) {
 		rc_gather = rc;
@@ -2355,7 +2359,7 @@ int migrate_pages(struct list_head *from, new_folio_t get_new_folio,
 	rc_gather += rc;
 
 	rc = migrate_lru_folios(from, get_new_folio, put_new_folio,
-			private, mode, reason, &ret_folios, &stats);
+			private, &ctl, &ret_folios, &stats);
 	if (rc < 0) {
 		rc_gather = rc;
 		goto out;
@@ -2382,8 +2386,8 @@ int migrate_pages(struct list_head *from, new_folio_t get_new_folio,
 	count_vm_events(THP_MIGRATION_SPLIT, stats.nr_thp_split);
 	trace_mm_migrate_pages(stats.nr_succeeded, stats.nr_failed_pages,
 			       stats.nr_thp_succeeded, stats.nr_thp_failed,
-			       stats.nr_thp_split, stats.nr_split, mode,
-			       reason);
+			       stats.nr_thp_split, stats.nr_split, ctl.mode,
+			       ctl.reason);
 
 	if (ret_succeeded)
 		*ret_succeeded = stats.nr_succeeded;

-- 
2.43.0



  parent reply	other threads:[~2026-09-02 10:55 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 10:52 [PATCH RFC 00/11] mm/migrate: separate migration paths and carry migration policy Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 01/11] mm/migrate: extract folio unmap phase Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 02/11] mm/migrate: handle retries in migrate_folios_move() Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 03/11] mm/migrate: factor out folio splitting on allocation failure Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 04/11] mm/migrate: use a dedicated list for hugetlb folios Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 05/11] mm/migrate: add a dedicated movable_ops migration pass Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 06/11] mm/migrate: rename migrate_pages_batch() to migrate_folios_batch() Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 07/11] mm/migrate: add migrate_lru_folios() entry point Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 08/11] mm/migrate: move LRU batching into migrate_lru_folios() Shivank Garg
2026-09-02 10:52 ` Shivank Garg [this message]
2026-09-02 11:19   ` [sos-linux-ext-patches] [PATCH RFC 09/11] mm/migrate: thread migration policy through a control struct Garg, Shivank
2026-09-02 10:52 ` [PATCH RFC 10/11] mm/migrate: pass migrate_control to migrate_pages() Shivank Garg
2026-09-02 10:52 ` [PATCH RFC 11/11] mm/migrate: pass migrate_control to migrate_folio() Shivank Garg
2026-09-02 11:10   ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260902-migrate-refactor-shivank-v1-9-9dcca87669c4@amd.com \
    --to=shivankg@amd.com \
    --cc=akpm@linux-foundation.org \
    --cc=anna@kernel.org \
    --cc=apopple@nvidia.com \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=bcrl@kvack.org \
    --cc=bharata@amd.com \
    --cc=brauner@kernel.org \
    --cc=brendan.jackman@linux.dev \
    --cc=byungchul@sk.com \
    --cc=clm@fb.com \
    --cc=corbet@lwn.net \
    --cc=damon@lists.linux.dev \
    --cc=david@kernel.org \
    --cc=dsterba@suse.com \
    --cc=gourry@gourry.net \
    --cc=hannes@cmpxchg.org \
    --cc=jack@suse.cz \
    --cc=jfs-discussion@lists.sourceforge.net \
    --cc=jgg@ziepe.ca \
    --cc=jhubbard@nvidia.com \
    --cc=joshua.hahnjy@gmail.com \
    --cc=kasong@tencent.com \
    --cc=kvm@vger.kernel.org \
    --cc=linmiaohe@huawei.com \
    --cc=linux-aio@kvack.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=matthew.brost@intel.com \
    --cc=mhocko@suse.com \
    --cc=muchun.song@linux.dev \
    --cc=nao.horiguchi@gmail.com \
    --cc=osalvador@suse.de \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qi.zheng@linux.dev \
    --cc=rakie.kim@sk.com \
    --cc=rdunlap@infradead.org \
    --cc=rientjes@google.com \
    --cc=rppt@kernel.org \
    --cc=seanjc@google.com \
    --cc=shaggy@kernel.org \
    --cc=shakeel.butt@linux.dev \
    --cc=sj@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=surenb@google.com \
    --cc=trondmy@kernel.org \
    --cc=vbabka@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --cc=yiannis@zptcorp.com \
    --cc=ying.huang@linux.alibaba.com \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox