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 <sudaraja@codeaurora.org>
[cgoldswo@codeaurora.org: Fix merge conflicts, add GKI #ifdef guards]
Signed-off-by: Chris Goldsworthy <cgoldswo@codeaurora.org>
This commit is contained in:
Sudarshan Rajagopalan 2019-10-09 15:01:23 -07:00 committed by Chris Goldsworthy
parent 68f85c607c
commit fb23f8fa6a
3 changed files with 24 additions and 0 deletions

View File

@ -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,

View File

@ -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

View File

@ -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