diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index b48c3471c254..cacaabea8a09 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -8,6 +8,7 @@ extern struct page_ext_operations page_owner_ops; extern void __reset_page_owner(struct page *page, unsigned int order); extern void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask); +extern gfp_t __get_page_owner_gfp(struct page *page); static inline void reset_page_owner(struct page *page, unsigned int order) { @@ -25,6 +26,14 @@ static inline void set_page_owner(struct page *page, __set_page_owner(page, order, gfp_mask); } + +static inline gfp_t get_page_owner_gfp(struct page *page) +{ + if (likely(!page_owner_inited)) + return 0; + + return __get_page_owner_gfp(page); +} #else static inline void reset_page_owner(struct page *page, unsigned int order) { @@ -33,6 +42,10 @@ static inline void set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) { } +static inline gfp_t get_page_owner_gfp(struct page *page) +{ + return 0; +} #endif /* CONFIG_PAGE_OWNER */ #endif /* __LINUX_PAGE_OWNER_H */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index fbba675a0bd9..ef19f22b2b7d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1948,6 +1948,7 @@ void free_hot_cold_page_list(struct list_head *list, bool cold) void split_page(struct page *page, unsigned int order) { int i; + gfp_t gfp_mask; VM_BUG_ON_PAGE(PageCompound(page), page); VM_BUG_ON_PAGE(!page_count(page), page); @@ -1961,10 +1962,11 @@ void split_page(struct page *page, unsigned int order) split_page(virt_to_page(page[0].shadow), order); #endif - set_page_owner(page, 0, 0); + gfp_mask = get_page_owner_gfp(page); + set_page_owner(page, 0, gfp_mask); for (i = 1; i < (1 << order); i++) { set_page_refcounted(page + i); - set_page_owner(page + i, 0, 0); + set_page_owner(page + i, 0, gfp_mask); } } EXPORT_SYMBOL_GPL(split_page); @@ -1994,7 +1996,7 @@ int __isolate_free_page(struct page *page, unsigned int order) zone->free_area[order].nr_free--; rmv_page_order(page); - set_page_owner(page, order, 0); + set_page_owner(page, order, __GFP_MOVABLE); /* Set the pageblock if the isolated page is at least a pageblock */ if (order >= pageblock_order - 1) { diff --git a/mm/page_owner.c b/mm/page_owner.c index bd5f842b56d2..983c3a10fa07 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -76,6 +76,13 @@ void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) __set_bit(PAGE_EXT_OWNER, &page_ext->flags); } +gfp_t __get_page_owner_gfp(struct page *page) +{ + struct page_ext *page_ext = lookup_page_ext(page); + + return page_ext->gfp_mask; +} + static ssize_t print_page_owner(char __user *buf, size_t count, unsigned long pfn, struct page *page, struct page_ext *page_ext)