Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7ba0eef authored by KAMEZAWA Hiroyuki's avatar KAMEZAWA Hiroyuki Committed by Linus Torvalds
Browse files

memcg: fix double free and make refcnt sane



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: default avatarDaisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Signed-off-by: default avatarKAMEZAWA 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 03f3c433
Loading
Loading
Loading
Loading
+6 −15
Original line number Diff line number Diff line
@@ -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);

@@ -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);
}


@@ -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);
}

@@ -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,