diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index debdc25f08b9..3b211d8d1798 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -3,11 +3,14 @@ #define __LINUX_PAGE_OWNER_H #include +#include #ifdef CONFIG_PAGE_OWNER extern struct static_key_false page_owner_inited; extern struct page_ext_operations page_owner_ops; +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 short order); extern void __set_page_owner(struct page *page, unsigned short order, gfp_t gfp_mask); diff --git a/mm/page_owner.c b/mm/page_owner.c index 2d6360eaccbb..af74143f057d 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -143,6 +142,25 @@ static inline struct page_owner *get_page_owner(struct page_ext *page_ext) return page_ext_data(page_ext, &page_owner_ops); } +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 (!static_branch_unlikely(&page_owner_inited)) + 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_NS_GPL(get_page_owner_handle, MINIDUMP); + static noinline depot_stack_handle_t save_stack(gfp_t flags) { unsigned long entries[PAGE_OWNER_STACK_DEPTH];