Skip to content

Commit

Permalink
memcg: fix double free and make refcnt sane
Browse files Browse the repository at this point in the history
1. Fix double-free BUG in error route of mem_cgroup_create().
    mem_cgroup_free() itself frees per-zone-info.
 2. Making refcnt of memcg simple.
    Add 1 refcnt at creation and call free when refcnt goes down to 0.

Reviewed-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
KAMEZAWA Hiroyuki authored and Linus Torvalds committed Jan 8, 2009
1 parent 03f3c43 commit a7ba0ee
Showing 1 changed file with 6 additions and 15 deletions.
21 changes: 6 additions & 15 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -2092,14 +2092,10 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
* Removal of cgroup itself succeeds regardless of refs from swap.
*/

static void mem_cgroup_free(struct mem_cgroup *mem)
static void __mem_cgroup_free(struct mem_cgroup *mem)
{
int node;

if (atomic_read(&mem->refcnt) > 0)
return;


for_each_node_state(node, N_POSSIBLE)
free_mem_cgroup_per_zone_info(mem, node);

Expand All @@ -2116,11 +2112,8 @@ static void mem_cgroup_get(struct mem_cgroup *mem)

static void mem_cgroup_put(struct mem_cgroup *mem)
{
if (atomic_dec_and_test(&mem->refcnt)) {
if (!mem->obsolete)
return;
mem_cgroup_free(mem);
}
if (atomic_dec_and_test(&mem->refcnt))
__mem_cgroup_free(mem);
}


Expand Down Expand Up @@ -2170,12 +2163,10 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)

if (parent)
mem->swappiness = get_swappiness(parent);

atomic_set(&mem->refcnt, 1);
return &mem->css;
free_out:
for_each_node_state(node, N_POSSIBLE)
free_mem_cgroup_per_zone_info(mem, node);
mem_cgroup_free(mem);
__mem_cgroup_free(mem);
return ERR_PTR(-ENOMEM);
}

Expand All @@ -2190,7 +2181,7 @@ static void mem_cgroup_pre_destroy(struct cgroup_subsys *ss,
static void mem_cgroup_destroy(struct cgroup_subsys *ss,
struct cgroup *cont)
{
mem_cgroup_free(mem_cgroup_from_cont(cont));
mem_cgroup_put(mem_cgroup_from_cont(cont));
}

static int mem_cgroup_populate(struct cgroup_subsys *ss,
Expand Down

0 comments on commit a7ba0ee

Please sign in to comment.