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

mm: page_owner: add support for splitting to any order in split page_owner

It adds a new_order parameter to set new page order in page owner. It
prepares for upcoming changes to support split huge page to any lower
order.

Link: https://lkml.kernel.org/r/20240226205534.1603748-7-zi.yan@sent.com
Signed-off-by: Zi Yan <ziy@nvidia.com>
Cc: David Hildenbrand <david@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Michal Koutny <mkoutny@suse.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Yang Shi <shy828301@gmail.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Zach O'Keefe <zokeefe@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Zi Yan and committed by
Andrew Morton
46d44d09 b8791381

+14 -12
+8 -5
include/linux/page_owner.h
··· 11 11 extern void __reset_page_owner(struct page *page, unsigned short order); 12 12 extern void __set_page_owner(struct page *page, 13 13 unsigned short order, gfp_t gfp_mask); 14 - extern void __split_page_owner(struct page *page, int order); 14 + extern void __split_page_owner(struct page *page, int old_order, 15 + int new_order); 15 16 extern void __folio_copy_owner(struct folio *newfolio, struct folio *old); 16 17 extern void __set_page_owner_migrate_reason(struct page *page, int reason); 17 18 extern void __dump_page_owner(const struct page *page); ··· 32 31 __set_page_owner(page, order, gfp_mask); 33 32 } 34 33 35 - static inline void split_page_owner(struct page *page, int order) 34 + static inline void split_page_owner(struct page *page, int old_order, 35 + int new_order) 36 36 { 37 37 if (static_branch_unlikely(&page_owner_inited)) 38 - __split_page_owner(page, order); 38 + __split_page_owner(page, old_order, new_order); 39 39 } 40 40 static inline void folio_copy_owner(struct folio *newfolio, struct folio *old) 41 41 { ··· 58 56 { 59 57 } 60 58 static inline void set_page_owner(struct page *page, 61 - unsigned int order, gfp_t gfp_mask) 59 + unsigned short order, gfp_t gfp_mask) 62 60 { 63 61 } 64 - static inline void split_page_owner(struct page *page, int order) 62 + static inline void split_page_owner(struct page *page, int old_order, 63 + int new_order) 65 64 { 66 65 } 67 66 static inline void folio_copy_owner(struct folio *newfolio, struct folio *folio)
+1 -1
mm/huge_memory.c
··· 2933 2933 unlock_page_lruvec(lruvec); 2934 2934 /* Caller disabled irqs, so they are still disabled here */ 2935 2935 2936 - split_page_owner(head, order); 2936 + split_page_owner(head, order, 0); 2937 2937 2938 2938 /* See comment in __split_huge_page_tail() */ 2939 2939 if (PageAnon(head)) {
+2 -2
mm/page_alloc.c
··· 2616 2616 2617 2617 for (i = 1; i < (1 << order); i++) 2618 2618 set_page_refcounted(page + i); 2619 - split_page_owner(page, order); 2619 + split_page_owner(page, order, 0); 2620 2620 split_page_memcg(page, order, 0); 2621 2621 } 2622 2622 EXPORT_SYMBOL_GPL(split_page); ··· 4801 4801 struct page *page = virt_to_page((void *)addr); 4802 4802 struct page *last = page + nr; 4803 4803 4804 - split_page_owner(page, order); 4804 + split_page_owner(page, order, 0); 4805 4805 split_page_memcg(page, order, 0); 4806 4806 while (page < --last) 4807 4807 set_page_refcounted(last);
+3 -4
mm/page_owner.c
··· 306 306 page_ext_put(page_ext); 307 307 } 308 308 309 - void __split_page_owner(struct page *page, int order) 309 + void __split_page_owner(struct page *page, int old_order, int new_order) 310 310 { 311 311 int i; 312 312 struct page_ext *page_ext = page_ext_get(page); 313 313 struct page_owner *page_owner; 314 - unsigned int nr = 1 << order; 315 314 316 315 if (unlikely(!page_ext)) 317 316 return; 318 317 319 - for (i = 0; i < nr; i++) { 318 + for (i = 0; i < (1 << old_order); i++) { 320 319 page_owner = get_page_owner(page_ext); 321 - page_owner->order = 0; 320 + page_owner->order = new_order; 322 321 page_ext = page_ext_next(page_ext); 323 322 } 324 323 page_ext_put(page_ext);