diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 9afd655ff646c9610b3c43e2fa40d4fe057ac7a0..7da3f6c660f5746529e1991d7251cbdeac2007f6 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -318,6 +318,10 @@ struct mem_cgroup { /* WARNING: nodeinfo must be the last member here */ }; +struct mem_cgroup_extension { + struct mem_cgroup memcg; +}; + /* * size of first charge trial. "32" comes from vmscan.c's magic value. * TODO: maybe necessary to use big numbers in big irons. diff --git a/mm/memcontrol.c b/mm/memcontrol.c index dca37f310b7b6511664d1798ebcf4d2972b9c8d9..ea67a63a4e713f1e972d53bdd06e782cbf6f9e59 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4508,11 +4508,14 @@ static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) static void __mem_cgroup_free(struct mem_cgroup *memcg) { int node; + struct mem_cgroup_extension *memcg_ext; for_each_node(node) free_mem_cgroup_per_node_info(memcg, node); free_percpu(memcg->stat_cpu); - kfree(memcg); + + memcg_ext = container_of(memcg, struct mem_cgroup_extension, memcg); + kfree(memcg_ext); } static void mem_cgroup_free(struct mem_cgroup *memcg) @@ -4524,13 +4527,15 @@ static void mem_cgroup_free(struct mem_cgroup *memcg) static struct mem_cgroup *mem_cgroup_alloc(void) { struct mem_cgroup *memcg; + struct mem_cgroup_extension *memcg_ext; size_t size; int node; - size = sizeof(struct mem_cgroup); + size = sizeof(struct mem_cgroup_extension); size += nr_node_ids * sizeof(struct mem_cgroup_per_node *); - memcg = kzalloc(size, GFP_KERNEL); + memcg_ext = kzalloc(size, GFP_KERNEL); + memcg = &memcg_ext->memcg; if (!memcg) return NULL;