[Devel] [PATCH rh7 2/3] memcg: count oom kills

Vladimir Davydov vdavydov at parallels.com
Thu May 21 02:50:25 PDT 2015


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 1bab6f0e2b38..5393f5f3b7d5 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 8e4331340571..70dd91ab37df 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -283,6 +283,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;
 
@@ -1597,6 +1598,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 a6928b4939cc..7201f7c39e3e 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)),
-- 
1.7.10.4




More information about the Devel mailing list