From 68f85c607ce83cfb5d56529a5858272917c96acb Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Tue, 25 Feb 2020 14:24:29 -0800 Subject: [PATCH 1/5] mm/Kconfig: Re-add HAVE_USERSPACE_LOW_MEMORY_KILLER When Android has a userspace low memory killer, we want to configure certain parts of the reclaim paths in the kernel. HAVE_USERSPACE_LOW_MEMORY_KILLER can be used to perform this configuration, and was removed when reverting a patch that defined it. Re-add it. Change-Id: Ic069c92a9d7928f0402705df8375d5384e9f743c Signed-off-by: Chris Goldsworthy --- mm/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/Kconfig b/mm/Kconfig index 4a8b6d55ae4d..2c5a3693e769 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -759,6 +759,17 @@ config PERCPU_STATS information includes global and per chunk statistics, which can be used to help understand percpu memory usage. +config HAVE_USERSPACE_LOW_MEMORY_KILLER + bool "Configure reclaim paths if there is a userspace LMK" + default n + help + Configures parts of the reclaim paths in the kernel when Android + has a userspace memory killer. This configuration is done for + functional (e.g. ensuring the OOM killer doesn't run at certain + points) and performance purposes (e.g. preventing log-spew + when the OOM killer and userspace memory killer both have the + potential to run). + config GUP_BENCHMARK bool "Enable infrastructure for get_user_pages_fast() benchmarking" help From fb23f8fa6a897ada4c8ab7dde1c236dee44ff719 Mon Sep 17 00:00:00 2001 From: Sudarshan Rajagopalan Date: Wed, 9 Oct 2019 15:01:23 -0700 Subject: [PATCH 2/5] 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 From 83d2497e08aab6e49623d075c16b9ba15e1d918f Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Tue, 25 Feb 2020 13:25:15 -0800 Subject: [PATCH 3/5] defconfig: lahaina: Expose additional page debugging info Enable CONFIG_PAGE_EXTENSION_PAGE_FREE and CONFIG_PAGE_FREE_TIME, which provides information on (1) if a page from buddy is free or not, (2) the timestamp of when a given page was freed, if it currently is free. Change-Id: I702c93192e031bbeb023879e47c2202f0c8d65f9 Signed-off-by: Chris Goldsworthy --- arch/arm64/configs/vendor/lahaina_debug.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/vendor/lahaina_debug.config b/arch/arm64/configs/vendor/lahaina_debug.config index d8e6c0987570..1db3e2ff7ac8 100644 --- a/arch/arm64/configs/vendor/lahaina_debug.config +++ b/arch/arm64/configs/vendor/lahaina_debug.config @@ -10,6 +10,7 @@ CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_PAGE_POISONING=y CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y +CONFIG_PAGE_EXTENSION_PAGE_FREE=y # CONFIG_DEBUG_DMA_BUF_REF is not set # CONFIG_PAGE_POISONING_NO_SANITY is not set # CONFIG_PAGE_POISONING_ZERO is not set From 90ec8176a8300d75b9b0142facbe655888df7422 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Fri, 18 Oct 2019 17:34:17 -0700 Subject: [PATCH 4/5] mm/oom-kill: Add option to panic when killing foreground app This setting is useful to debug memory intensive test scenarios, which are close to the limit of what the device supports. Change-Id: Id09f43736bd3c9586b4dac4fae570e78089f5bb3 Signed-off-by: Patrick Daly [cgoldswo@codeaurora.org: Add macro introduced in obsolete patch] Signed-off-by: Chris Goldsworthy --- include/linux/oom.h | 2 ++ kernel/signal.c | 1 + mm/oom_kill.c | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/include/linux/oom.h b/include/linux/oom.h index 40862dd4f223..c880273c6199 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -130,4 +130,6 @@ extern int sysctl_reap_mem_on_sigkill; /* calls for LMK reaper */ extern void add_to_oom_reaper(struct task_struct *p); +extern void check_panic_on_foreground_kill(struct task_struct *p); +#define ULMK_MAGIC "lmkd" #endif /* _INCLUDE_LINUX_OOM_H */ diff --git a/kernel/signal.c b/kernel/signal.c index e8f1ce7a7e47..1ae3e276e51b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1406,6 +1406,7 @@ int group_send_sig_info(int sig, struct kernel_siginfo *info, rcu_read_unlock(); if (!ret && sig) { + check_panic_on_foreground_kill(p); ret = do_send_sig_info(sig, info, p, type); if (capable(CAP_KILL) && sig == SIGKILL) add_to_oom_reaper(p); diff --git a/mm/oom_kill.c b/mm/oom_kill.c index c19945135938..987a84f72c7b 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -58,6 +58,9 @@ int sysctl_oom_kill_allocating_task; int sysctl_oom_dump_tasks = 1; int sysctl_reap_mem_on_sigkill = 1; +static int panic_on_adj_zero; +module_param(panic_on_adj_zero, int, 0644); + /* * Serializes oom killer invocations (out_of_memory()) from all contexts to * prevent from over eager oom killing (e.g. when the oom killer is invoked @@ -1197,3 +1200,18 @@ void add_to_oom_reaper(struct task_struct *p) put_task_struct(p); } + +/* + * Should be called prior to sending sigkill. To guarantee that the + * process to-be-killed is still untouched. + */ +void check_panic_on_foreground_kill(struct task_struct *p) +{ + if (unlikely(!strcmp(current->comm, ULMK_MAGIC) + && p->signal->oom_score_adj == 0 + && panic_on_adj_zero)) { + show_mem(SHOW_MEM_FILTER_NODES, NULL); + show_mem_call_notifiers(); + panic("Attempt to kill foreground task: %s", p->comm); + } +} From 7e10ca7b4405eaa7705c706cb8e2e1855b46ab9f Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Tue, 25 Feb 2020 09:36:04 -0800 Subject: [PATCH 5/5] mm/oom-kill: Remove obsolete IS_ENABLED check CONFIG_HAVE_LOW_MEMORY_KILLER is no longer present on 5.4, so remove a check to see if it's enabled or not. Change-Id: Ifcd88a0e29b7da6dede7f98fcb4c99ffc7bf3c02 Signed-off-by: Chris Goldsworthy --- mm/oom_kill.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 987a84f72c7b..d0cece9bdd15 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -1158,8 +1158,7 @@ void pagefault_out_of_memory(void) .order = 0, }; - if (IS_ENABLED(CONFIG_HAVE_LOW_MEMORY_KILLER) || - IS_ENABLED(CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER)) + if (IS_ENABLED(CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER)) return; if (mem_cgroup_oom_synchronize(true))