From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by aws-us-west-2-korg-lkml-1.web.codeaurora.org (Postfix) with ESMTP id 3C334C5CFC1 for ; Fri, 15 Jun 2018 09:52:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CEA4B20896 for ; Fri, 15 Jun 2018 09:52:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QjL9Lc3H" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CEA4B20896 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965544AbeFOJwg (ORCPT ); Fri, 15 Jun 2018 05:52:36 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:36157 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755912AbeFOJwe (ORCPT ); Fri, 15 Jun 2018 05:52:34 -0400 Received: by mail-pf0-f194.google.com with SMTP id a12-v6so4641227pfi.3 for ; Fri, 15 Jun 2018 02:52:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=TN5+jQjFvVR4sfQpR0aVzCl6O6JxOoHeXeritnUv0LQ=; b=QjL9Lc3H33yfcS6rliTA+bWChZwIfCriNLtDynAdk1GR4pec/w/7K8CxJeIGf6U0T5 wMJrN5ROu+z0stk4YOZmx3ldQJL77W9pjNwTHc1fw1e0k2vORKQA/kEyqkwANNqPLSDv zzA7KOZwR/XccbB0JefOlJoUyFNBDe8c6Y4kNIxdO2QtjbGUEebG/LyeVz8VYJCEAn4U ALO/reQ0oVdCbNJbTnOERMpCSYEj2khB4Wq+nLFXb6PHq7pi18gERoM5r2M7eez8kSHu z2nzRNAsCbQjaDXueUYnwoL+zYVNOXmxuOjs9OHkGvcADvzgQm5/2S8zdZUTVcuywoYb 4/DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=TN5+jQjFvVR4sfQpR0aVzCl6O6JxOoHeXeritnUv0LQ=; b=aDXOBQSLJ54v+oMU4Z+TIexm8h+lzGNXvm8sSbYu1kP7fK/LFtPKlea9UiccnqNzUb QIl0SynSd/L8re0e7xpHP5Xge2w573z0tW+m4a6u0tmdX0tUFvwPRFrp5dVpV+bh+c2X AsDw/PVeB0/S8MOIlGrKDFCzPD5CQ78IU4j6JcM2Sr4vxo28ZIoBZMbgx7WZY4b/8v7r v1rUlnOJzHlFnFJdoP7JPiHC5j5x8i2LekjqrI/TsGmpo3PviFDBJtqOgv5zhHXE875D 50jNxct+p1o/cmc6FYJ9IDhRUFW2cIEnVSboIn+ttv6vbsxUn117ksA0YX9a9Xxz+xKL Lsvg== X-Gm-Message-State: APt69E2yxNn1eJXZHeRB9Y2pZLurUwMgjQ7d/vzJNy+5UhK1KEfoE9H3 Kc6b1ffgs9DpOxpsZk98u+k= X-Google-Smtp-Source: ADUXVKIVdDp7/b0IK5OvzMXtCXV+wJTSmQLVbYT9OHvn1jcbOj+UFesdD1q+XhL6aW6oCc96gbnpQQ== X-Received: by 2002:a63:7b0e:: with SMTP id w14-v6mr909437pgc.165.1529056354065; Fri, 15 Jun 2018 02:52:34 -0700 (PDT) Received: from dest.didichuxing.com ([52.229.160.192]) by smtp.gmail.com with ESMTPSA id b72-v6sm15270056pfj.56.2018.06.15.02.52.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Jun 2018 02:52:33 -0700 (PDT) From: ufo19890607@gmail.com To: akpm@linux-foundation.org, mhocko@suse.com, rientjes@google.com, kirill.shutemov@linux.intel.com, aarcange@redhat.com, penguin-kernel@i-love.sakura.ne.jp, guro@fb.com, yang.s@alibaba-inc.com Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, yuzhoujian@didichuxing.com Subject: [PATCH v9] Refactor part of the oom report in dump_header Date: Fri, 15 Jun 2018 17:52:21 +0800 Message-Id: <1529056341-16182-1-git-send-email-ufo19890607@gmail.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: yuzhoujian Some users complains that system-wide oom report does not print memcg's name which contains the task killed by the oom-killer. The current system wide oom report prints the task's command, gfp_mask, order ,oom_score_adj and shows the memory info, but misses some important information, etc. the memcg that has reached its limit and the memcg to which the killed process is attached. I follow the advices of David Rientjes and Michal Hocko, and refactor part of the oom report. After this patch, users can get the memcg's path from the oom report and check the certain container more quickly. The oom print info after this patch: oom-kill:constraint=,nodemask=,origin_memcg=,kill_memcg=,task=,pid=,uid= Signed-off-by: yuzhoujian --- Below is the part of the oom report in the dmesg ... [ 142.158316] panic cpuset=/ mems_allowed=0-1 [ 142.158983] CPU: 15 PID: 8682 Comm: panic Not tainted 4.17.0+ #13 [ 142.159659] Hardware name: Inspur SA5212M4/YZMB-00370-107, BIOS 4.1.10 11/14/2016 [ 142.160342] Call Trace: [ 142.161037] dump_stack+0x78/0xb3 [ 142.161734] dump_header+0x7d/0x334 [ 142.162433] oom_kill_process+0x228/0x490 [ 142.163126] ? oom_badness+0x2a/0x130 [ 142.163821] out_of_memory+0xf0/0x280 [ 142.164532] __alloc_pages_slowpath+0x711/0xa07 [ 142.165241] __alloc_pages_nodemask+0x23f/0x260 [ 142.165947] alloc_pages_vma+0x73/0x180 [ 142.166665] do_anonymous_page+0xed/0x4e0 [ 142.167388] __handle_mm_fault+0xbd2/0xe00 [ 142.168114] handle_mm_fault+0x116/0x250 [ 142.168841] __do_page_fault+0x233/0x4d0 [ 142.169567] do_page_fault+0x32/0x130 [ 142.170303] ? page_fault+0x8/0x30 [ 142.171036] page_fault+0x1e/0x30 [ 142.171764] RIP: 0033:0x7f403000a860 [ 142.172517] RSP: 002b:00007ffc9f745c28 EFLAGS: 00010206 [ 142.173268] RAX: 00007f3f6fd7d000 RBX: 0000000000000000 RCX: 00007f3f7f5cd000 [ 142.174040] RDX: 00007f3fafd7d000 RSI: 0000000000000000 RDI: 00007f3f6fd7d000 [ 142.174806] RBP: 00007ffc9f745c50 R08: ffffffffffffffff R09: 0000000000000000 [ 142.175623] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000400490 [ 142.176542] R13: 00007ffc9f745d30 R14: 0000000000000000 R15: 0000000000000000 [ 142.177709] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),origin_memcg=(null),kill_memcg=/test/test1/test2,task=panic,pid= 8622,uid= 0 ... Changes since v8: - add the constraint in the oom_control structure. - put enum oom_constraint and constraint array into the oom.h file. - simplify the description for mem_cgroup_print_oom_context. Changes since v7: - add the constraint parameter to dump_header and oom_kill_process. - remove the static char array in the mem_cgroup_print_oom_context, and invoke pr_cont_cgroup_path to print memcg' name. - combine the patchset v6 into one. Changes since v6: - divide the patch v5 into two parts. One part is to add an array of const char and put enum oom_constraint into the memcontrol.h; the other is will refactor the output in the dump_header. - limit the memory usage for the static char array by using NAME_MAX in the mem_cgroup_print_oom_context. - eliminate the spurious spaces in the oom's output and fix the spelling of "constrain". Changes since v5: - add an array of const char for each constraint. - replace all of the pr_cont with a single line print of the pr_info. - put enum oom_constraint into the memcontrol.c file for printing oom constraint. Changes since v4: - rename the helper's name to mem_cgroup_print_oom_context. - rename the mem_cgroup_print_oom_info to mem_cgroup_print_oom_meminfo. - add the constrain info in the dump_header. Changes since v3: - rename the helper's name to mem_cgroup_print_oom_memcg_name. - add the rcu lock held to the helper. - remove the print info of memcg's name in mem_cgroup_print_oom_info. Changes since v2: - add the mem_cgroup_print_memcg_name helper to print the memcg's name which contains the task that will be killed by the oom-killer. Changes since v1: - replace adding mem_cgroup_print_oom_info with printing the memcg's name only. include/linux/memcontrol.h | 16 +++++++++++++--- include/linux/oom.h | 17 +++++++++++++++++ mm/memcontrol.c | 41 ++++++++++++++++++++++++++++++----------- mm/oom_kill.c | 24 +++++++++--------------- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 6c6fb116e925..d62390fca414 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -30,6 +30,7 @@ #include #include #include +#include struct mem_cgroup; struct page; @@ -491,8 +492,11 @@ void mem_cgroup_handle_over_high(void); unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); -void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, - struct task_struct *p); +void mem_cgroup_print_oom_context(struct mem_cgroup *memcg, + struct task_struct *p, enum oom_constraint constraint, + nodemask_t *nodemask); + +void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg); static inline void mem_cgroup_oom_enable(void) { @@ -903,7 +907,13 @@ static inline unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) } static inline void -mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) +mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p, + enum oom_constraint constraint, nodemask_t *nodemask) +{ +} + +static inline void +mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) { } diff --git a/include/linux/oom.h b/include/linux/oom.h index 6adac113e96d..5bed78d4bfb8 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -15,6 +15,20 @@ struct notifier_block; struct mem_cgroup; struct task_struct; +enum oom_constraint { + CONSTRAINT_NONE, + CONSTRAINT_CPUSET, + CONSTRAINT_MEMORY_POLICY, + CONSTRAINT_MEMCG, +}; + +static const char * const oom_constraint_text[] = { + [CONSTRAINT_NONE] = "CONSTRAINT_NONE", + [CONSTRAINT_CPUSET] = "CONSTRAINT_CPUSET", + [CONSTRAINT_MEMORY_POLICY] = "CONSTRAINT_MEMORY_POLICY", + [CONSTRAINT_MEMCG] = "CONSTRAINT_MEMCG", +}; + /* * Details of the page allocation that triggered the oom killer that are used to * determine what should be killed. @@ -42,6 +56,9 @@ struct oom_control { unsigned long totalpages; struct task_struct *chosen; unsigned long chosen_points; + + /* Used to print the constraint info. */ + enum oom_constraint constraint; }; extern struct mutex oom_lock; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e6f0d5ef320a..7e0704bdff01 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1119,32 +1119,51 @@ static const char *const memcg1_stat_names[] = { #define K(x) ((x) << (PAGE_SHIFT-10)) /** - * mem_cgroup_print_oom_info: Print OOM information relevant to memory controller. - * @memcg: The memory cgroup that went over limit + * mem_cgroup_print_oom_context: Print OOM context information relevant to + * memory controller. + * @memcg: The origin memory cgroup that went over limit * @p: Task that is going to be killed + * @constraint: The allocation constraint + * @nodemask: The allocation nodemask * * NOTE: @memcg and @p's mem_cgroup can be different when hierarchy is * enabled */ -void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) +void mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p, + enum oom_constraint constraint, nodemask_t *nodemask) { - struct mem_cgroup *iter; - unsigned int i; + struct cgroup *origin_cgrp, *kill_cgrp; rcu_read_lock(); + pr_info("oom-kill:constraint=%s,nodemask=%*pbl,origin_memcg=", + oom_constraint_text[constraint], nodemask_pr_args(nodemask)); + + if (memcg) + pr_cont_cgroup_path(memcg->css.cgroup); + else + pr_cont("(null)"); + if (p) { - pr_info("Task in "); + pr_cont(",kill_memcg="); pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id)); - pr_cont(" killed as a result of limit of "); - } else { - pr_info("Memory limit reached of cgroup "); + pr_cont(",task=%s,pid=%5d,uid=%5d", + p->comm, p->pid, from_kuid(&init_user_ns, task_uid(p))); } - - pr_cont_cgroup_path(memcg->css.cgroup); pr_cont("\n"); rcu_read_unlock(); +} + +/** + * mem_cgroup_print_oom_info: Print OOM memory information relevant to + * memory controller. + * @memcg: The memory cgroup that went over limit + */ +void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) +{ + struct mem_cgroup *iter; + unsigned int i; pr_info("memory: usage %llukB, limit %llukB, failcnt %lu\n", K((u64)page_counter_read(&memcg->memory)), diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 84081e77bc51..1db70cec0c16 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -237,13 +237,6 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, return points > 0 ? points : 1; } -enum oom_constraint { - CONSTRAINT_NONE, - CONSTRAINT_CPUSET, - CONSTRAINT_MEMORY_POLICY, - CONSTRAINT_MEMCG, -}; - /* * Determine the type of allocation constraint. */ @@ -430,8 +423,10 @@ static void dump_header(struct oom_control *oc, struct task_struct *p) cpuset_print_current_mems_allowed(); dump_stack(); + mem_cgroup_print_oom_context(oc->memcg, p, + oc->constraint, oc->nodemask); if (is_memcg_oom(oc)) - mem_cgroup_print_oom_info(oc->memcg, p); + mem_cgroup_print_oom_meminfo(oc->memcg); else { show_mem(SHOW_MEM_FILTER_NODES, oc->nodemask); if (is_dump_unreclaim_slabs()) @@ -973,8 +968,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) /* * Determines whether the kernel must panic because of the panic_on_oom sysctl. */ -static void check_panic_on_oom(struct oom_control *oc, - enum oom_constraint constraint) +static void check_panic_on_oom(struct oom_control *oc) { if (likely(!sysctl_panic_on_oom)) return; @@ -984,7 +978,7 @@ static void check_panic_on_oom(struct oom_control *oc, * does not panic for cpuset, mempolicy, or memcg allocation * failures. */ - if (constraint != CONSTRAINT_NONE) + if (oc->constraint != CONSTRAINT_NONE) return; } /* Do not panic for oom kills triggered by sysrq */ @@ -1021,8 +1015,8 @@ EXPORT_SYMBOL_GPL(unregister_oom_notifier); bool out_of_memory(struct oom_control *oc) { unsigned long freed = 0; - enum oom_constraint constraint = CONSTRAINT_NONE; + oc->constraint = CONSTRAINT_NONE; if (oom_killer_disabled) return false; @@ -1057,10 +1051,10 @@ bool out_of_memory(struct oom_control *oc) * Check if there were limitations on the allocation (only relevant for * NUMA and memcg) that may require different handling. */ - constraint = constrained_alloc(oc); - if (constraint != CONSTRAINT_MEMORY_POLICY) + oc->constraint = constrained_alloc(oc); + if (oc->constraint != CONSTRAINT_MEMORY_POLICY) oc->nodemask = NULL; - check_panic_on_oom(oc, constraint); + check_panic_on_oom(oc); if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task && current->mm && !oom_unkillable_task(current, NULL, oc->nodemask) && -- 2.14.1