[Devel] [PATCH RHEL7 COMMIT] memcg: count oom kills

Konstantin Khorenko khorenko at virtuozzo.com
Thu May 28 09:03:41 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.7
------>
commit 1e6252a0fb0ce20b668cf7c5a6529b05fa7895cf
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Thu May 28 20:03:41 2015 +0400

    memcg: count oom kills
    
    Patchset description:
    
    This patch set adds memory.oom_guarantee file to memory cgroup which
    allows to protect a memory cgroup from OOM killer. It works as follows:
    OOM killer first selects from processes in cgroups that are above their
    OOM guarantee, and only if there is no such it switches to scanning
    processes from all cgroups. This behavior is similar to UB_OOMGUARPAGES.
    
    It also adds OOM kills counter to each memory cgroup and synchronizes
    beancounters' UB_OOMGUARPAGES resource with oom_guarantee/oom_kill_cnt
    obtained from mem_cgroup.
    
    Related to https://jira.sw.ru/browse/PSBM-20089
    
    Vladimir Davydov (3):
      memcg: add oom_guarantee
      memcg: count oom kills
      memcg: sync UB_OOMGUARPAGES
    
    This patch description:
    
    Whenever a task is OOM-killed, increment OOM kill counter in the memory
    cgroup it belongs to and all its ascendants.
    
    Required by UBC API (UB_OOMGUARPAGES.failcnt).
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/linux/memcontrol.h |  7 +++++++
 mm/memcontrol.c            | 23 +++++++++++++++++++++++
 mm/oom_kill.c              |  1 +
 3 files changed, 31 insertions(+)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 98bd35f..661e60c 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -121,6 +121,8 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *memcg);
 unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list);
 void mem_cgroup_update_lru_size(struct lruvec *, enum lru_list, int);
 extern bool mem_cgroup_below_oom_guarantee(struct task_struct *p);
+extern void mem_cgroup_note_oom_kill(struct mem_cgroup *memcg,
+				     struct mm_struct *mm);
 extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg,
 					struct task_struct *p);
 extern void mem_cgroup_replace_page_cache(struct page *oldpage,
@@ -349,6 +351,11 @@ static inline bool mem_cgroup_below_oom_guarantee(struct task_struct *p)
 }
 
 static inline void
+mem_cgroup_note_oom_kill(struct mem_cgroup *memcg, struct mm_struct *mm)
+{
+}
+
+static inline void
 mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 {
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 1849b48..4dad5bd 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -291,6 +291,7 @@ struct mem_cgroup {
 	unsigned long long swap_max;
 	atomic_long_t mem_failcnt;
 	atomic_long_t swap_failcnt;
+	atomic_long_t oom_kill_cnt;
 
 	unsigned long long oom_guarantee;
 
@@ -1605,6 +1606,28 @@ bool mem_cgroup_below_oom_guarantee(struct task_struct *p)
 	return ret;
 }
 
+void mem_cgroup_note_oom_kill(struct mem_cgroup *root_memcg,
+			      struct mm_struct *mm)
+{
+	struct mem_cgroup *memcg, *memcg_to_put;
+
+	if (!root_memcg)
+		root_memcg = root_mem_cgroup;
+
+	memcg_to_put = memcg = try_get_mem_cgroup_from_mm(mm);
+	if (!memcg || !mem_cgroup_same_or_subtree(root_memcg, memcg))
+		memcg = root_memcg;
+
+	for (; memcg; memcg = parent_mem_cgroup(memcg)) {
+		atomic_long_inc(&memcg->oom_kill_cnt);
+		if (memcg == root_memcg)
+			break;
+	}
+
+	if (memcg_to_put)
+		css_put(&memcg_to_put->css);
+}
+
 #define mem_cgroup_from_res_counter(counter, member)	\
 	container_of(counter, struct mem_cgroup, member)
 
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index a6928b4..7201f7c 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -488,6 +488,7 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
 
 	/* mm cannot safely be dereferenced after task_unlock(victim) */
 	mm = victim->mm;
+	mem_cgroup_note_oom_kill(memcg, mm);
 	pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
 		task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
 		K(get_mm_counter(victim->mm, MM_ANONPAGES)),



More information about the Devel mailing list