Welcome! Share code as fast as possible.

diff --git a/mm/migrate.c b/mm/migrate.c
index 477acf996951..9327c993bdb6 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1878,7 +1878,7 @@ static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,
 		struct list_head *ret_folios, struct list_head *split_folios,
 		struct migrate_pages_stats *stats)
 {
-	int rc, nr_failed = 0;
+	int rc, nr_failed = 0, consec_failures = 0;
 	LIST_HEAD(folios);
 	struct migrate_pages_stats astats;
 
@@ -1909,17 +1909,43 @@ static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,
 	 * isn't counted
 	 */
 	list_splice_tail_init(&folios, from);
 	while (!list_empty(from)) {
 		list_move(from->next, &folios);
 		rc = migrate_pages_batch(&folios, get_new_folio, put_new_folio,
 					 private, mode, reason, ret_folios,
-					 split_folios, stats, NR_MAX_MIGRATE_SYNC_RETRY);
+					 split_folios, stats, 1);
 		list_splice_tail_init(&folios, ret_folios);
+		if (!rc) {
+			consec_failures = 0;
+			continue;
+		}
 		if (rc < 0)
 			return rc;
-		nr_failed += rc;
+		if (++consec_failures >= NR_MAX_MIGRATE_SYNC_RETRY) {
+			/*
+			 * We retried NR_MAX_MIGRATE_SYNC_RETRY times
+			 * and got consecutive failures; do not add
+			 * this folio back to fromlist to ensure
+			 * migration terminates eventually
+			 */
+			nr_failed += rc;
+			consec_failures = 0;
+			continue;
+		}
+		/* Push failed folio to tail of fromlist */
+		list_move_tail(ret_folios->next, from);
 	}
 
 	return nr_failed;
 }