Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/migrate: remove MIGRATEPAGE_UNMAP

migrate_folio_unmap() is the only user of MIGRATEPAGE_UNMAP. We want to
remove MIGRATEPAGE_* completely.

It's rather weird to have a generic MIGRATEPAGE_UNMAP, documented to be
returned from address-space callbacks, when it's only used for an internal
helper.

Let's start by having only a single "success" return value for
migrate_folio_unmap() -- 0 -- by moving the "folio was already freed"
check into the single caller.

There is a remaining comment for PG_isolated, which we renamed to
PG_movable_ops_isolated recently and forgot to update.

While we might still run into that case with zsmalloc, it's something we
want to get rid of soon. So let's just focus that optimization on real
folios only for now by excluding movable_ops pages. Note that concurrent
freeing can happen at any time and this "already freed" check is not
relevant for correctness.

[david@redhat.com: no need to pass "reason" to migrate_folio_unmap(), per Lance]
Link: https://lkml.kernel.org/r/3bb725f8-28d7-4aa2-b75f-af40d5cab280@redhat.com
Link: https://lkml.kernel.org/r/20250811143949.1117439-2-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Chris Mason <clm@fb.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dave Kleikamp <shaggy@kernel.org>
Cc: David Sterba <dsterba@suse.com>
Cc: Eugenio Pé rez <eperezma@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Gregory Price <gourry@gourry.net>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Jerrin Shaji George <jerrin.shaji-george@broadcom.com>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mathew Brost <matthew.brost@intel.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Cc: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

David Hildenbrand and committed by
Andrew Morton
95c2908f 1f205275

+22 -24
-1
include/linux/migrate.h
··· 18 18 * - zero on page migration success; 19 19 */ 20 20 #define MIGRATEPAGE_SUCCESS 0 21 - #define MIGRATEPAGE_UNMAP 1 22 21 23 22 /** 24 23 * struct movable_operations - Driver page migration
+22 -23
mm/migrate.c
··· 1189 1189 static int migrate_folio_unmap(new_folio_t get_new_folio, 1190 1190 free_folio_t put_new_folio, unsigned long private, 1191 1191 struct folio *src, struct folio **dstp, enum migrate_mode mode, 1192 - enum migrate_reason reason, struct list_head *ret) 1192 + struct list_head *ret) 1193 1193 { 1194 1194 struct folio *dst; 1195 1195 int rc = -EAGAIN; ··· 1197 1197 struct anon_vma *anon_vma = NULL; 1198 1198 bool locked = false; 1199 1199 bool dst_locked = false; 1200 - 1201 - if (folio_ref_count(src) == 1) { 1202 - /* Folio was freed from under us. So we are done. */ 1203 - folio_clear_active(src); 1204 - folio_clear_unevictable(src); 1205 - /* free_pages_prepare() will clear PG_isolated. */ 1206 - list_del(&src->lru); 1207 - migrate_folio_done(src, reason); 1208 - return MIGRATEPAGE_SUCCESS; 1209 - } 1210 1200 1211 1201 dst = get_new_folio(src, private); 1212 1202 if (!dst) ··· 1287 1297 1288 1298 if (unlikely(page_has_movable_ops(&src->page))) { 1289 1299 __migrate_folio_record(dst, old_page_state, anon_vma); 1290 - return MIGRATEPAGE_UNMAP; 1300 + return 0; 1291 1301 } 1292 1302 1293 1303 /* ··· 1317 1327 1318 1328 if (!folio_mapped(src)) { 1319 1329 __migrate_folio_record(dst, old_page_state, anon_vma); 1320 - return MIGRATEPAGE_UNMAP; 1330 + return 0; 1321 1331 } 1322 1332 1323 1333 out: ··· 1860 1870 continue; 1861 1871 } 1862 1872 1873 + /* 1874 + * If we are holding the last folio reference, the folio 1875 + * was freed from under us, so just drop our reference. 1876 + */ 1877 + if (likely(!page_has_movable_ops(&folio->page)) && 1878 + folio_ref_count(folio) == 1) { 1879 + folio_clear_active(folio); 1880 + folio_clear_unevictable(folio); 1881 + list_del(&folio->lru); 1882 + migrate_folio_done(folio, reason); 1883 + stats->nr_succeeded += nr_pages; 1884 + stats->nr_thp_succeeded += is_thp; 1885 + continue; 1886 + } 1887 + 1863 1888 rc = migrate_folio_unmap(get_new_folio, put_new_folio, 1864 - private, folio, &dst, mode, reason, 1865 - ret_folios); 1889 + private, folio, &dst, mode, ret_folios); 1866 1890 /* 1867 1891 * The rules are: 1868 - * Success: folio will be freed 1869 - * Unmap: folio will be put on unmap_folios list, 1870 - * dst folio put on dst_folios list 1892 + * 0: folio will be put on unmap_folios list, 1893 + * dst folio put on dst_folios list 1871 1894 * -EAGAIN: stay on the from list 1872 1895 * -ENOMEM: stay on the from list 1873 1896 * Other errno: put on ret_folios list ··· 1930 1927 thp_retry += is_thp; 1931 1928 nr_retry_pages += nr_pages; 1932 1929 break; 1933 - case MIGRATEPAGE_SUCCESS: 1934 - stats->nr_succeeded += nr_pages; 1935 - stats->nr_thp_succeeded += is_thp; 1936 - break; 1937 - case MIGRATEPAGE_UNMAP: 1930 + case 0: 1938 1931 list_move_tail(&folio->lru, &unmap_folios); 1939 1932 list_add_tail(&dst->lru, &dst_folios); 1940 1933 break;