Commit 947b3dd1 authored by Michal Hocko's avatar Michal Hocko Committed by Linus Torvalds

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: default avatarMichal Hocko <mhocko@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: default avatarDavid Rientjes <rientjes@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 286549dc
...@@ -1647,13 +1647,13 @@ static void move_unlock_mem_cgroup(struct mem_cgroup *memcg, ...@@ -1647,13 +1647,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) 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 * protects memcg_name and makes sure that parallel ooms do not
* on the assumption that OOM is serialized for memory controller. * interleave
* If this assumption is broken, revisit this code.
*/ */
static DEFINE_SPINLOCK(oom_info_lock);
struct cgroup *task_cgrp;
struct cgroup *mem_cgrp;
static char memcg_name[PATH_MAX]; static char memcg_name[PATH_MAX];
int ret; int ret;
struct mem_cgroup *iter; struct mem_cgroup *iter;
...@@ -1662,6 +1662,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) ...@@ -1662,6 +1662,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
if (!p) if (!p)
return; return;
spin_lock(&oom_info_lock);
rcu_read_lock(); rcu_read_lock();
mem_cgrp = memcg->css.cgroup; mem_cgrp = memcg->css.cgroup;
...@@ -1730,6 +1731,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) ...@@ -1730,6 +1731,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
pr_cont("\n"); pr_cont("\n");
} }
spin_unlock(&oom_info_lock);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment