[Devel] [PATCH RHEL7 COMMIT] memcg, oom: lock mem_cgroup_print_oom_info

Vladimir Davydov vdavydov at virtuozzo.com
Tue Sep 8 08:31:00 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-229.7.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.6.8
------>
commit 8e902df7d2e4171db87b4a8481d90a40002e30a5
Author: Michal Hocko <mhocko at suse.cz>
Date:   Tue Sep 8 19:31:00 2015 +0400

    memcg, oom: lock mem_cgroup_print_oom_info
    
    mem_cgroup_print_oom_info uses a static buffer (memcg_name) to store the
    name of the cgroup.  This is not safe as pointed out by David Rientjes
    because memcg oom is locked only for its hierarchy and nothing prevents
    another parallel hierarchy to trigger oom as well and overwrite the
    already in-use buffer.
    
    This patch introduces oom_info_lock hidden inside
    mem_cgroup_print_oom_info which is held throughout the function.  It
    makes access to memcg_name safe and as a bonus it also prevents parallel
    memcg ooms to interleave their statistics which would make the printed
    data hard to analyze otherwise.
    
    Signed-off-by: Michal Hocko <mhocko at suse.cz>
    Cc: Johannes Weiner <hannes at cmpxchg.org>
    Cc: KOSAKI Motohiro <kosaki.motohiro at jp.fujitsu.com>
    Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
    Acked-by: David Rientjes <rientjes at google.com>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
    (cherry picked from commit 947b3dd1a84ba3fcb7163688fdc36671941786f4)
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 mm/memcontrol.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 59a2f05a8b92..54bad06b0200 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1819,13 +1819,13 @@ static void move_unlock_mem_cgroup(struct mem_cgroup *memcg,
  */
 void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 {
-	struct cgroup *task_cgrp;
-	struct cgroup *mem_cgrp;
 	/*
-	 * Need a buffer in BSS, can't rely on allocations. The code relies
-	 * on the assumption that OOM is serialized for memory controller.
-	 * If this assumption is broken, revisit this code.
+	 * protects memcg_name and makes sure that parallel ooms do not
+	 * interleave
 	 */
+	static DEFINE_SPINLOCK(oom_info_lock);
+	struct cgroup *task_cgrp;
+	struct cgroup *mem_cgrp;
 	static char memcg_name[PATH_MAX];
 	int ret;
 	struct mem_cgroup *iter;
@@ -1834,6 +1834,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 	if (!p)
 		return;
 
+	spin_lock(&oom_info_lock);
 	rcu_read_lock();
 
 	mem_cgrp = memcg->css.cgroup;
@@ -1902,6 +1903,7 @@ done:
 
 		pr_cont("\n");
 	}
+	spin_unlock(&oom_info_lock);
 }
 
 /*



More information about the Devel mailing list