From: Michal Hocko Subject: [PATCH] mm, oom: report compaction/migration stats for higher order requests Date: Sun, 14 Aug 2016 14:53:27 +0200 Message-ID: <20160814125327.GF9248@dhcp22.suse.cz> References: <201608120901.41463.a.miskiewicz@gmail.com> <20160812074340.GC3639@dhcp22.suse.cz> <20160814125111.GE9248@dhcp22.suse.cz> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: linux-ext4@vger.kernel.org, linux-mm@vger.kernel.org To: arekm@maven.pl Return-path: Received: from mail-wm0-f65.google.com ([74.125.82.65]:36521 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751015AbcHNMxa (ORCPT ); Sun, 14 Aug 2016 08:53:30 -0400 Content-Disposition: inline In-Reply-To: <20160814125111.GE9248@dhcp22.suse.cz> Sender: linux-ext4-owner@vger.kernel.org List-ID: From: Michal Hocko Both oom and the allocation failure reports are not providing any information about the compaction/migration counters which might give us a clue what went wrong and why we are OOM for the particular order - e.g. the compaction fails constantly because it cannot isolate any pages or that the migration fails. So far we have been asking for /proc/vmstat content before and after the OOM which is rather clumsy, especially when the OOM is not 100% reproducible. Extend show_mem() to understand a new filter (SHOW_COMPACTION_STATS) which is enabled only for higer order paths. Signed-off-by: Michal Hocko --- include/linux/mm.h | 1 + lib/show_mem.c | 14 ++++++++++++++ mm/oom_kill.c | 2 +- mm/page_alloc.c | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 7e44613c5078..b4859547acc4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1146,6 +1146,7 @@ extern void pagefault_out_of_memory(void); * various contexts. */ #define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ +#define SHOW_COMPACTION_STATS (0x0002u) extern void show_free_areas(unsigned int flags); extern bool skip_free_areas_node(unsigned int flags, int nid); diff --git a/lib/show_mem.c b/lib/show_mem.c index 1feed6a2b12a..595ba00f5836 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c @@ -8,6 +8,7 @@ #include #include #include +#include void show_mem(unsigned int filter) { @@ -17,6 +18,19 @@ void show_mem(unsigned int filter) printk("Mem-Info:\n"); show_free_areas(filter); +#ifdef CONFIG_COMPACTION + if (filter & SHOW_COMPACTION_STATS) { + printk("compaction_stall:%lu compaction_fail:%lu " + "compact_migrate_scanned:%lu compact_free_scanned:%lu " + "compact_isolated:%lu " + "pgmigrate_success:%lu pgmigrate_fail:%lu\n", + global_page_state(COMPACTSTALL), global_page_state(COMPACTFAIL), + global_page_state(COMPACTMIGRATE_SCANNED), global_page_state(COMPACTFAIL), + global_page_state(COMPACTISOLATED), + global_page_state(PGMIGRATE_SUCCESS), global_page_state(PGMIGRATE_FAIL)); + } +#endif + for_each_online_pgdat(pgdat) { unsigned long flags; int zoneid; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 463cdd22d4e0..5e7a09f4dbc9 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -419,7 +419,7 @@ static void dump_header(struct oom_control *oc, struct task_struct *p) if (oc->memcg) mem_cgroup_print_oom_info(oc->memcg, p); else - show_mem(SHOW_MEM_FILTER_NODES); + show_mem(SHOW_MEM_FILTER_NODES | (oc->order)?SHOW_COMPACTION_STATS:0); if (sysctl_oom_dump_tasks) dump_tasks(oc->memcg, oc->nodemask); } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9d46b65061be..adf0cb655827 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2999,6 +2999,8 @@ void warn_alloc_failed(gfp_t gfp_mask, unsigned int order, const char *fmt, ...) pr_warn("%s: page allocation failure: order:%u, mode:%#x(%pGg)\n", current->comm, order, gfp_mask, &gfp_mask); dump_stack(); + if (order) + filter |= SHOW_COMPACTION_STATS; if (!should_suppress_show_mem()) show_mem(filter); } -- 2.8.1 -- Michal Hocko SUSE Labs