From fb23f8fa6a897ada4c8ab7dde1c236dee44ff719 Mon Sep 17 00:00:00 2001 From: Sudarshan Rajagopalan Date: Wed, 9 Oct 2019 15:01:23 -0700 Subject: [PATCH] mm, page_owner: set page owner info for tail pages When allocating higher order pages, currently only the head page is set with page owner info, leaving the tail pages with previous or stale info. This patch sets the info for tail pages too and sets the time of free in page owner info of all pages during free. This patch also adds an extra info to page extension flags to help check if page is in buddy or not. Change-Id: I96d13485af698d586a4dd7b1092a379a645c8fcb Signed-off-by: Sudarshan Rajagopalan [cgoldswo@codeaurora.org: Fix merge conflicts, add GKI #ifdef guards] Signed-off-by: Chris Goldsworthy --- include/linux/page_ext.h | 3 +++ mm/Kconfig.debug | 9 +++++++++ mm/page_owner.c | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index cfce186f0c4e..e50acd1810c9 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -19,6 +19,9 @@ struct page_ext_operations { enum page_ext_flags { PAGE_EXT_OWNER, PAGE_EXT_OWNER_ALLOCATED, +#ifdef CONFIG_PAGE_EXTENSION_PAGE_FREE + PAGE_EXT_PG_FREE, +#endif #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) PAGE_EXT_YOUNG, PAGE_EXT_IDLE, diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug index 46615e0bdb35..14e36729c3d6 100644 --- a/mm/Kconfig.debug +++ b/mm/Kconfig.debug @@ -8,6 +8,15 @@ config PAGE_EXTENSION by not allocating this extra memory according to boottime configuration. +config PAGE_EXTENSION_PAGE_FREE + bool "Add a flag in page_ext_flags to indicate if a page is free" + depends on PAGE_EXTENSION && QGKI + help + Add the PAGE_FREE flag in page_ext_flags, in order to indicate + whether a page from the buddy allocator is free or is in + use. This information can aid in debugging buddy allocator + related issues. + config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL diff --git a/mm/page_owner.c b/mm/page_owner.c index 41a99cfe0b0d..35673f47d8af 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -29,6 +29,7 @@ struct page_owner { depot_stack_handle_t free_handle; int pid; u64 ts_nsec; + u64 free_ts_nsec; }; static bool page_owner_enabled = IS_ENABLED(CONFIG_PAGE_OWNER_ENABLE_DEFAULT); @@ -152,6 +153,7 @@ void __reset_page_owner(struct page *page, unsigned int order) struct page_ext *page_ext; depot_stack_handle_t handle = 0; struct page_owner *page_owner; + u64 free_ts_nsec = local_clock(); handle = save_stack(GFP_NOWAIT | __GFP_NOWARN); @@ -160,8 +162,12 @@ void __reset_page_owner(struct page *page, unsigned int order) return; for (i = 0; i < (1 << order); i++) { __clear_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags); +#ifdef CONFIG_PAGE_EXTENSION_PAGE_FREE + __set_bit(PAGE_EXT_PG_FREE, &page_ext->flags); +#endif page_owner = get_page_owner(page_ext); page_owner->free_handle = handle; + page_owner->free_ts_nsec = free_ts_nsec; page_ext = page_ext_next(page_ext); } } @@ -181,8 +187,13 @@ static inline void __set_page_owner_handle(struct page *page, page_owner->last_migrate_reason = -1; page_owner->pid = current->pid; page_owner->ts_nsec = local_clock(); + page_owner->free_ts_nsec = 0; + __set_bit(PAGE_EXT_OWNER, &page_ext->flags); __set_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags); +#ifdef CONFIG_PAGE_EXTENSION_PAGE_FREE + __clear_bit(PAGE_EXT_PG_FREE, &page_ext->flags); +#endif page_ext = page_ext_next(page_ext); } @@ -247,6 +258,7 @@ void __copy_page_owner(struct page *oldpage, struct page *newpage) new_page_owner->handle = old_page_owner->handle; new_page_owner->pid = old_page_owner->pid; new_page_owner->ts_nsec = old_page_owner->ts_nsec; + new_page_owner->free_ts_nsec = old_page_owner->ts_nsec; /* * We don't clear the bit on the oldpage as it's going to be freed