@@ -1687,6 +1687,81 @@ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
1687
1687
return nr_failed ;
1688
1688
}
1689
1689
1690
+ static void migrate_folios_move (struct list_head * src_folios ,
1691
+ struct list_head * dst_folios ,
1692
+ free_folio_t put_new_folio , unsigned long private ,
1693
+ enum migrate_mode mode , int reason ,
1694
+ struct list_head * ret_folios ,
1695
+ struct migrate_pages_stats * stats ,
1696
+ int * retry , int * thp_retry , int * nr_failed ,
1697
+ int * nr_retry_pages )
1698
+ {
1699
+ struct folio * folio , * folio2 , * dst , * dst2 ;
1700
+ bool is_thp ;
1701
+ int nr_pages ;
1702
+ int rc ;
1703
+
1704
+ dst = list_first_entry (dst_folios , struct folio , lru );
1705
+ dst2 = list_next_entry (dst , lru );
1706
+ list_for_each_entry_safe (folio , folio2 , src_folios , lru ) {
1707
+ is_thp = folio_test_large (folio ) && folio_test_pmd_mappable (folio );
1708
+ nr_pages = folio_nr_pages (folio );
1709
+
1710
+ cond_resched ();
1711
+
1712
+ rc = migrate_folio_move (put_new_folio , private ,
1713
+ folio , dst , mode ,
1714
+ reason , ret_folios );
1715
+ /*
1716
+ * The rules are:
1717
+ * Success: folio will be freed
1718
+ * -EAGAIN: stay on the unmap_folios list
1719
+ * Other errno: put on ret_folios list
1720
+ */
1721
+ switch (rc ) {
1722
+ case - EAGAIN :
1723
+ * retry += 1 ;
1724
+ * thp_retry += is_thp ;
1725
+ * nr_retry_pages += nr_pages ;
1726
+ break ;
1727
+ case MIGRATEPAGE_SUCCESS :
1728
+ stats -> nr_succeeded += nr_pages ;
1729
+ stats -> nr_thp_succeeded += is_thp ;
1730
+ break ;
1731
+ default :
1732
+ * nr_failed += 1 ;
1733
+ stats -> nr_thp_failed += is_thp ;
1734
+ stats -> nr_failed_pages += nr_pages ;
1735
+ break ;
1736
+ }
1737
+ dst = dst2 ;
1738
+ dst2 = list_next_entry (dst , lru );
1739
+ }
1740
+ }
1741
+
1742
+ static void migrate_folios_undo (struct list_head * src_folios ,
1743
+ struct list_head * dst_folios ,
1744
+ free_folio_t put_new_folio , unsigned long private ,
1745
+ struct list_head * ret_folios )
1746
+ {
1747
+ struct folio * folio , * folio2 , * dst , * dst2 ;
1748
+
1749
+ dst = list_first_entry (dst_folios , struct folio , lru );
1750
+ dst2 = list_next_entry (dst , lru );
1751
+ list_for_each_entry_safe (folio , folio2 , src_folios , lru ) {
1752
+ int old_page_state = 0 ;
1753
+ struct anon_vma * anon_vma = NULL ;
1754
+
1755
+ __migrate_folio_extract (dst , & old_page_state , & anon_vma );
1756
+ migrate_folio_undo_src (folio , old_page_state & PAGE_WAS_MAPPED ,
1757
+ anon_vma , true, ret_folios );
1758
+ list_del (& dst -> lru );
1759
+ migrate_folio_undo_dst (dst , true, put_new_folio , private );
1760
+ dst = dst2 ;
1761
+ dst2 = list_next_entry (dst , lru );
1762
+ }
1763
+ }
1764
+
1690
1765
/*
1691
1766
* migrate_pages_batch() first unmaps folios in the from list as many as
1692
1767
* possible, then move the unmapped folios.
@@ -1709,7 +1784,7 @@ static int migrate_pages_batch(struct list_head *from,
1709
1784
int pass = 0 ;
1710
1785
bool is_thp = false;
1711
1786
bool is_large = false;
1712
- struct folio * folio , * folio2 , * dst = NULL , * dst2 ;
1787
+ struct folio * folio , * folio2 , * dst = NULL ;
1713
1788
int rc , rc_saved = 0 , nr_pages ;
1714
1789
LIST_HEAD (unmap_folios );
1715
1790
LIST_HEAD (dst_folios );
@@ -1880,42 +1955,11 @@ static int migrate_pages_batch(struct list_head *from,
1880
1955
thp_retry = 0 ;
1881
1956
nr_retry_pages = 0 ;
1882
1957
1883
- dst = list_first_entry (& dst_folios , struct folio , lru );
1884
- dst2 = list_next_entry (dst , lru );
1885
- list_for_each_entry_safe (folio , folio2 , & unmap_folios , lru ) {
1886
- is_thp = folio_test_large (folio ) && folio_test_pmd_mappable (folio );
1887
- nr_pages = folio_nr_pages (folio );
1888
-
1889
- cond_resched ();
1890
-
1891
- rc = migrate_folio_move (put_new_folio , private ,
1892
- folio , dst , mode ,
1893
- reason , ret_folios );
1894
- /*
1895
- * The rules are:
1896
- * Success: folio will be freed
1897
- * -EAGAIN: stay on the unmap_folios list
1898
- * Other errno: put on ret_folios list
1899
- */
1900
- switch (rc ) {
1901
- case - EAGAIN :
1902
- retry ++ ;
1903
- thp_retry += is_thp ;
1904
- nr_retry_pages += nr_pages ;
1905
- break ;
1906
- case MIGRATEPAGE_SUCCESS :
1907
- stats -> nr_succeeded += nr_pages ;
1908
- stats -> nr_thp_succeeded += is_thp ;
1909
- break ;
1910
- default :
1911
- nr_failed ++ ;
1912
- stats -> nr_thp_failed += is_thp ;
1913
- stats -> nr_failed_pages += nr_pages ;
1914
- break ;
1915
- }
1916
- dst = dst2 ;
1917
- dst2 = list_next_entry (dst , lru );
1918
- }
1958
+ /* Move the unmapped folios */
1959
+ migrate_folios_move (& unmap_folios , & dst_folios ,
1960
+ put_new_folio , private , mode , reason ,
1961
+ ret_folios , stats , & retry , & thp_retry ,
1962
+ & nr_failed , & nr_retry_pages );
1919
1963
}
1920
1964
nr_failed += retry ;
1921
1965
stats -> nr_thp_failed += thp_retry ;
@@ -1924,20 +1968,8 @@ static int migrate_pages_batch(struct list_head *from,
1924
1968
rc = rc_saved ? : nr_failed ;
1925
1969
out :
1926
1970
/* Cleanup remaining folios */
1927
- dst = list_first_entry (& dst_folios , struct folio , lru );
1928
- dst2 = list_next_entry (dst , lru );
1929
- list_for_each_entry_safe (folio , folio2 , & unmap_folios , lru ) {
1930
- int old_page_state = 0 ;
1931
- struct anon_vma * anon_vma = NULL ;
1932
-
1933
- __migrate_folio_extract (dst , & old_page_state , & anon_vma );
1934
- migrate_folio_undo_src (folio , old_page_state & PAGE_WAS_MAPPED ,
1935
- anon_vma , true, ret_folios );
1936
- list_del (& dst -> lru );
1937
- migrate_folio_undo_dst (dst , true, put_new_folio , private );
1938
- dst = dst2 ;
1939
- dst2 = list_next_entry (dst , lru );
1940
- }
1971
+ migrate_folios_undo (& unmap_folios , & dst_folios ,
1972
+ put_new_folio , private , ret_folios );
1941
1973
1942
1974
return rc ;
1943
1975
}
0 commit comments