diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index 302031e9b212..0340fb2e2fbd 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -9,6 +9,8 @@ extern struct static_key_false page_owner_inited; extern struct page_ext_operations page_owner_ops; extern struct page_owner *get_page_owner(struct page_ext *page_ext); +extern depot_stack_handle_t get_page_owner_handle(struct page_ext *page_ext, + unsigned long pfn); 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); diff --git a/mm/page_owner.c b/mm/page_owner.c index beb33ab7a996..6be7d57b0e37 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -104,6 +104,25 @@ struct page_owner *get_page_owner(struct page_ext *page_ext) } EXPORT_SYMBOL_GPL(get_page_owner); +depot_stack_handle_t get_page_owner_handle(struct page_ext *page_ext, unsigned long pfn) +{ + struct page_owner *page_owner; + depot_stack_handle_t handle; + + if (!page_owner_enabled) + return 0; + + page_owner = get_page_owner(page_ext); + + /* skip handle for tail pages of higher order allocations */ + if (!IS_ALIGNED(pfn, 1 << page_owner->order)) + return 0; + + handle = READ_ONCE(page_owner->handle); + return handle; +} +EXPORT_SYMBOL_GPL(get_page_owner_handle); + static inline bool check_recursive_alloc(unsigned long *entries, unsigned int nr_entries, unsigned long ip)