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: convert "movable" flag in page->mapping to a page flag

Instead, let's use a page flag. As the page flag can result in
false-positives, glue it to the page types for which we support/implement
movable_ops page migration.

We are reusing PG_uptodate, that is for example used to track file system
state and does not apply to movable_ops pages. So warning in case it is
set in page_has_movable_ops() on other page types could result in
false-positive warnings.

Likely we could set the bit using a non-atomic update: in contrast to
page->mapping, we could have others trying to update the flags
concurrently when trying to lock the folio. In
isolate_movable_ops_page(), we already take care of that by checking if
the page has movable_ops before locking it. Let's start with the atomic
variant, we could later switch to the non-atomic variant once we are sure
other cases are similarly fine. Once we perform the switch, we'll have to
introduce __SETPAGEFLAG_NOOP().

[david@redhat.com: add missing `:' in kerneldoc]
Link: https://lkml.kernel.org/r/d96e2916-2c43-462c-b6a1-2375ef397d8b@redhat.com
Link: https://lkml.kernel.org/r/20250704102524.326966-21-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Eugenio Pé rez <eperezma@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Gregory Price <gourry@gourry.net>
Cc: Harry Yoo <harry.yoo@oracle.com>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Jerrin Shaji George <jerrin.shaji-george@broadcom.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mathew Brost <matthew.brost@intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Cc: xu xin <xu.xin16@zte.com.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

David Hildenbrand and committed by
Andrew Morton
3d388584 84caf988

+46 -26
+1 -1
include/linux/balloon_compaction.h
··· 92 92 struct page *page) 93 93 { 94 94 __SetPageOffline(page); 95 - __SetPageMovable(page); 95 + SetPageMovableOps(page); 96 96 set_page_private(page, (unsigned long)balloon); 97 97 list_add(&page->lru, &balloon->pages); 98 98 }
-8
include/linux/migrate.h
··· 103 103 104 104 #endif /* CONFIG_MIGRATION */ 105 105 106 - #ifdef CONFIG_COMPACTION 107 - void __SetPageMovable(struct page *page); 108 - #else 109 - static inline void __SetPageMovable(struct page *page) 110 - { 111 - } 112 - #endif 113 - 114 106 #ifdef CONFIG_NUMA_BALANCING 115 107 int migrate_misplaced_folio_prepare(struct folio *folio, 116 108 struct vm_area_struct *vma, int node);
+44 -10
include/linux/page-flags.h
··· 170 170 /* non-lru isolated movable page */ 171 171 PG_isolated = PG_reclaim, 172 172 173 + #ifdef CONFIG_MIGRATION 174 + /* this is a movable_ops page (for selected typed pages only) */ 175 + PG_movable_ops = PG_uptodate, 176 + #endif 177 + 173 178 /* Only valid for buddy pages. Used to track pages that are reported */ 174 179 PG_reported = PG_uptodate, 175 180 ··· 703 698 * bit; and then folio->mapping points, not to an anon_vma, but to a private 704 699 * structure which KSM associates with that merged page. See ksm.h. 705 700 * 706 - * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is used for non-lru movable 707 - * page and then folio->mapping points to a struct movable_operations. 708 - * 709 701 * Please note that, confusingly, "folio_mapping" refers to the inode 710 702 * address_space which maps the folio from disk; whereas "folio_mapped" 711 703 * refers to user virtual address space into which the folio is mapped. ··· 745 743 { 746 744 return folio_test_anon(page_folio(page)); 747 745 } 748 - 749 - static __always_inline bool page_has_movable_ops(const struct page *page) 750 - { 751 - return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) == 752 - PAGE_MAPPING_MOVABLE; 753 - } 754 - 755 746 #ifdef CONFIG_KSM 756 747 /* 757 748 * A KSM page is one of those write-protected "shared pages" or "merged pages" ··· 1127 1132 bool is_free_buddy_page(const struct page *page); 1128 1133 1129 1134 PAGEFLAG(Isolated, isolated, PF_ANY); 1135 + 1136 + #ifdef CONFIG_MIGRATION 1137 + /* 1138 + * This page is migratable through movable_ops (for selected typed pages 1139 + * only). 1140 + * 1141 + * Page migration of such pages might fail, for example, if the page is 1142 + * already isolated by somebody else, or if the page is about to get freed. 1143 + * 1144 + * While a subsystem might set selected typed pages that support page migration 1145 + * as being movable through movable_ops, it must never clear this flag. 1146 + * 1147 + * This flag is only cleared when the page is freed back to the buddy. 1148 + * 1149 + * Only selected page types support this flag (see page_movable_ops()) and 1150 + * the flag might be used in other context for other pages. Always use 1151 + * page_has_movable_ops() instead. 1152 + */ 1153 + TESTPAGEFLAG(MovableOps, movable_ops, PF_NO_TAIL); 1154 + SETPAGEFLAG(MovableOps, movable_ops, PF_NO_TAIL); 1155 + #else /* !CONFIG_MIGRATION */ 1156 + TESTPAGEFLAG_FALSE(MovableOps, movable_ops); 1157 + SETPAGEFLAG_NOOP(MovableOps, movable_ops); 1158 + #endif /* CONFIG_MIGRATION */ 1159 + 1160 + /** 1161 + * page_has_movable_ops - test for a movable_ops page 1162 + * @page: The page to test. 1163 + * 1164 + * Test whether this is a movable_ops page. Such pages will stay that 1165 + * way until freed. 1166 + * 1167 + * Returns true if this is a movable_ops page, otherwise false. 1168 + */ 1169 + static inline bool page_has_movable_ops(const struct page *page) 1170 + { 1171 + return PageMovableOps(page) && 1172 + (PageOffline(page) || PageZsmalloc(page)); 1173 + } 1130 1174 1131 1175 static __always_inline int PageAnonExclusive(const struct page *page) 1132 1176 {
-6
mm/compaction.c
··· 114 114 } 115 115 116 116 #ifdef CONFIG_COMPACTION 117 - void __SetPageMovable(struct page *page) 118 - { 119 - VM_BUG_ON_PAGE(!PageLocked(page), page); 120 - page->mapping = (void *)(PAGE_MAPPING_MOVABLE); 121 - } 122 - EXPORT_SYMBOL(__SetPageMovable); 123 117 124 118 /* Do not skip compaction more than 64 times */ 125 119 #define COMPACT_MAX_DEFER_SHIFT 6
+1 -1
mm/zpdesc.h
··· 154 154 155 155 static inline void __zpdesc_set_movable(struct zpdesc *zpdesc) 156 156 { 157 - __SetPageMovable(zpdesc_page(zpdesc)); 157 + SetPageMovableOps(zpdesc_page(zpdesc)); 158 158 } 159 159 160 160 static inline void __zpdesc_set_zsmalloc(struct zpdesc *zpdesc)