@@ -1414,6 +1414,8 @@ static inline int try_split_folio(struct folio *folio, struct list_head *split_f
1414
1414
return rc ;
1415
1415
}
1416
1416
1417
+ #define NR_MAX_MIGRATE_PAGES_RETRY 10
1418
+
1417
1419
struct migrate_pages_stats {
1418
1420
int nr_succeeded ; /* Normal and large folios migrated successfully, in
1419
1421
units of base pages */
@@ -1424,6 +1426,95 @@ struct migrate_pages_stats {
1424
1426
int nr_thp_split ; /* THP split before migrating */
1425
1427
};
1426
1428
1429
+ /*
1430
+ * Returns the number of hugetlb folios that were not migrated, or an error code
1431
+ * after NR_MAX_MIGRATE_PAGES_RETRY attempts or if no hugetlb folios are movable
1432
+ * any more because the list has become empty or no retryable hugetlb folios
1433
+ * exist any more. It is caller's responsibility to call putback_movable_pages()
1434
+ * only if ret != 0.
1435
+ */
1436
+ static int migrate_hugetlbs (struct list_head * from , new_page_t get_new_page ,
1437
+ free_page_t put_new_page , unsigned long private ,
1438
+ enum migrate_mode mode , int reason ,
1439
+ struct migrate_pages_stats * stats ,
1440
+ struct list_head * ret_folios )
1441
+ {
1442
+ int retry = 1 ;
1443
+ int nr_failed = 0 ;
1444
+ int nr_retry_pages = 0 ;
1445
+ int pass = 0 ;
1446
+ struct folio * folio , * folio2 ;
1447
+ int rc , nr_pages ;
1448
+
1449
+ for (pass = 0 ; pass < NR_MAX_MIGRATE_PAGES_RETRY && retry ; pass ++ ) {
1450
+ retry = 0 ;
1451
+ nr_retry_pages = 0 ;
1452
+
1453
+ list_for_each_entry_safe (folio , folio2 , from , lru ) {
1454
+ if (!folio_test_hugetlb (folio ))
1455
+ continue ;
1456
+
1457
+ nr_pages = folio_nr_pages (folio );
1458
+
1459
+ cond_resched ();
1460
+
1461
+ rc = unmap_and_move_huge_page (get_new_page ,
1462
+ put_new_page , private ,
1463
+ & folio -> page , pass > 2 , mode ,
1464
+ reason , ret_folios );
1465
+ /*
1466
+ * The rules are:
1467
+ * Success: hugetlb folio will be put back
1468
+ * -EAGAIN: stay on the from list
1469
+ * -ENOMEM: stay on the from list
1470
+ * -ENOSYS: stay on the from list
1471
+ * Other errno: put on ret_folios list
1472
+ */
1473
+ switch (rc ) {
1474
+ case - ENOSYS :
1475
+ /* Hugetlb migration is unsupported */
1476
+ nr_failed ++ ;
1477
+ stats -> nr_failed_pages += nr_pages ;
1478
+ list_move_tail (& folio -> lru , ret_folios );
1479
+ break ;
1480
+ case - ENOMEM :
1481
+ /*
1482
+ * When memory is low, don't bother to try to migrate
1483
+ * other folios, just exit.
1484
+ */
1485
+ stats -> nr_failed_pages += nr_pages + nr_retry_pages ;
1486
+ return - ENOMEM ;
1487
+ case - EAGAIN :
1488
+ retry ++ ;
1489
+ nr_retry_pages += nr_pages ;
1490
+ break ;
1491
+ case MIGRATEPAGE_SUCCESS :
1492
+ stats -> nr_succeeded += nr_pages ;
1493
+ break ;
1494
+ default :
1495
+ /*
1496
+ * Permanent failure (-EBUSY, etc.):
1497
+ * unlike -EAGAIN case, the failed folio is
1498
+ * removed from migration folio list and not
1499
+ * retried in the next outer loop.
1500
+ */
1501
+ nr_failed ++ ;
1502
+ stats -> nr_failed_pages += nr_pages ;
1503
+ break ;
1504
+ }
1505
+ }
1506
+ }
1507
+ /*
1508
+ * nr_failed is number of hugetlb folios failed to be migrated. After
1509
+ * NR_MAX_MIGRATE_PAGES_RETRY attempts, give up and count retried hugetlb
1510
+ * folios as failed.
1511
+ */
1512
+ nr_failed += retry ;
1513
+ stats -> nr_failed_pages += nr_retry_pages ;
1514
+
1515
+ return nr_failed ;
1516
+ }
1517
+
1427
1518
/*
1428
1519
* migrate_pages - migrate the folios specified in a list, to the free folios
1429
1520
* supplied as the target for the page migration
@@ -1440,10 +1531,10 @@ struct migrate_pages_stats {
1440
1531
* @ret_succeeded: Set to the number of folios migrated successfully if
1441
1532
* the caller passes a non-NULL pointer.
1442
1533
*
1443
- * The function returns after 10 attempts or if no folios are movable any more
1444
- * because the list has become empty or no retryable folios exist any more.
1445
- * It is caller's responsibility to call putback_movable_pages() to return folios
1446
- * to the LRU or free list only if ret != 0.
1534
+ * The function returns after NR_MAX_MIGRATE_PAGES_RETRY attempts or if no folios
1535
+ * are movable any more because the list has become empty or no retryable folios
1536
+ * exist any more. It is caller's responsibility to call putback_movable_pages()
1537
+ * only if ret != 0.
1447
1538
*
1448
1539
* Returns the number of {normal folio, large folio, hugetlb} that were not
1449
1540
* migrated, or an error code. The number of large folio splits will be
@@ -1457,7 +1548,7 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
1457
1548
int retry = 1 ;
1458
1549
int large_retry = 1 ;
1459
1550
int thp_retry = 1 ;
1460
- int nr_failed = 0 ;
1551
+ int nr_failed ;
1461
1552
int nr_retry_pages = 0 ;
1462
1553
int nr_large_failed = 0 ;
1463
1554
int pass = 0 ;
@@ -1474,38 +1565,45 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
1474
1565
trace_mm_migrate_pages_start (mode , reason );
1475
1566
1476
1567
memset (& stats , 0 , sizeof (stats ));
1568
+ rc = migrate_hugetlbs (from , get_new_page , put_new_page , private , mode , reason ,
1569
+ & stats , & ret_folios );
1570
+ if (rc < 0 )
1571
+ goto out ;
1572
+ nr_failed = rc ;
1573
+
1477
1574
split_folio_migration :
1478
- for (pass = 0 ; pass < 10 && (retry || large_retry ); pass ++ ) {
1575
+ for (pass = 0 ;
1576
+ pass < NR_MAX_MIGRATE_PAGES_RETRY && (retry || large_retry );
1577
+ pass ++ ) {
1479
1578
retry = 0 ;
1480
1579
large_retry = 0 ;
1481
1580
thp_retry = 0 ;
1482
1581
nr_retry_pages = 0 ;
1483
1582
1484
1583
list_for_each_entry_safe (folio , folio2 , from , lru ) {
1584
+ /* Retried hugetlb folios will be kept in list */
1585
+ if (folio_test_hugetlb (folio )) {
1586
+ list_move_tail (& folio -> lru , & ret_folios );
1587
+ continue ;
1588
+ }
1589
+
1485
1590
/*
1486
1591
* Large folio statistics is based on the source large
1487
1592
* folio. Capture required information that might get
1488
1593
* lost during migration.
1489
1594
*/
1490
- is_large = folio_test_large (folio ) && ! folio_test_hugetlb ( folio ) ;
1595
+ is_large = folio_test_large (folio );
1491
1596
is_thp = is_large && folio_test_pmd_mappable (folio );
1492
1597
nr_pages = folio_nr_pages (folio );
1598
+
1493
1599
cond_resched ();
1494
1600
1495
- if (folio_test_hugetlb (folio ))
1496
- rc = unmap_and_move_huge_page (get_new_page ,
1497
- put_new_page , private ,
1498
- & folio -> page , pass > 2 , mode ,
1499
- reason ,
1500
- & ret_folios );
1501
- else
1502
- rc = unmap_and_move (get_new_page , put_new_page ,
1503
- private , folio , pass > 2 , mode ,
1504
- reason , & ret_folios );
1601
+ rc = unmap_and_move (get_new_page , put_new_page ,
1602
+ private , folio , pass > 2 , mode ,
1603
+ reason , & ret_folios );
1505
1604
/*
1506
1605
* The rules are:
1507
- * Success: non hugetlb folio will be freed, hugetlb
1508
- * folio will be put back
1606
+ * Success: folio will be freed
1509
1607
* -EAGAIN: stay on the from list
1510
1608
* -ENOMEM: stay on the from list
1511
1609
* -ENOSYS: stay on the from list
@@ -1532,7 +1630,6 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
1532
1630
stats .nr_thp_split += is_thp ;
1533
1631
break ;
1534
1632
}
1535
- /* Hugetlb migration is unsupported */
1536
1633
} else if (!no_split_folio_counting ) {
1537
1634
nr_failed ++ ;
1538
1635
}
@@ -1626,8 +1723,8 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
1626
1723
*/
1627
1724
if (!list_empty (& split_folios )) {
1628
1725
/*
1629
- * Move non-migrated folios (after 10 retries) to ret_folios
1630
- * to avoid migrating them again.
1726
+ * Move non-migrated folios (after NR_MAX_MIGRATE_PAGES_RETRY
1727
+ * retries) to ret_folios to avoid migrating them again.
1631
1728
*/
1632
1729
list_splice_init (from , & ret_folios );
1633
1730
list_splice_init (& split_folios , from );
0 commit comments