+++ /dev/null
-From: Jan Blunck <jblunck@suse.de>
-Subject: Dynamically allocate struct mem_cgroup_stat_cpu memory
-
-When increasing NR_CPUS to 4096 the size of struct mem_cgroup is growing to
-507904 bytes per instance on x86_64. This patch changes the allocation of
-these structures to use nr_cpu_ids instead. Although the init_mem_cgroup still
-is that huge since it stays statically allocated.
-
-Signed-off-by: Jan Blunck <jblunck@suse.de>
----
- mm/memcontrol.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 41 insertions(+), 8 deletions(-)
-
-Index: b/mm/memcontrol.c
-===================================================================
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -59,7 +59,7 @@ struct mem_cgroup_stat_cpu {
- } ____cacheline_aligned_in_smp;
-
- struct mem_cgroup_stat {
-- struct mem_cgroup_stat_cpu cpustat[NR_CPUS];
-+ struct mem_cgroup_stat_cpu *cpustat;
- };
-
- /*
-@@ -143,6 +143,7 @@ struct mem_cgroup {
- struct mem_cgroup_stat stat;
- };
- static struct mem_cgroup init_mem_cgroup;
-+static struct mem_cgroup_stat_cpu init_mem_cgroup_stat_cpu[NR_CPUS];
-
- /*
- * We use the lower bit of the page->page_cgroup pointer as a bit spin
-@@ -1097,23 +1098,54 @@ static void free_mem_cgroup_per_zone_inf
- static struct mem_cgroup *mem_cgroup_alloc(void)
- {
- struct mem_cgroup *mem;
-+ struct mem_cgroup_stat_cpu *cpustat;
-+ size_t statsize = nr_cpu_ids * sizeof(*cpustat);
-
-- if (sizeof(*mem) < PAGE_SIZE)
-- mem = kmalloc(sizeof(*mem), GFP_KERNEL);
-- else
-+ if (sizeof(*mem) > PAGE_SIZE) {
- mem = vmalloc(sizeof(*mem));
--
-- if (mem)
-+ if (!mem)
-+ goto out;
- memset(mem, 0, sizeof(*mem));
-+ } else
-+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-+
-+ if (!mem)
-+ goto out;
-+
-+ if (statsize > PAGE_SIZE) {
-+ cpustat = vmalloc(statsize);
-+ if (!cpustat)
-+ goto out_mem;
-+ memset(cpustat, 0, statsize);
-+ } else
-+ cpustat = kzalloc(statsize, GFP_KERNEL);
-+
-+ if (!cpustat)
-+ goto out_mem;
-+
-+ mem->stat.cpustat = cpustat;
- return mem;
-+
-+out_mem:
-+ if (is_vmalloc_addr(mem))
-+ vfree(mem);
-+ else
-+ kfree(mem);
-+out:
-+ return NULL;
- }
-
- static void mem_cgroup_free(struct mem_cgroup *mem)
- {
-- if (sizeof(*mem) < PAGE_SIZE)
-- kfree(mem);
-+ if (is_vmalloc_addr(mem->stat.cpustat))
-+ vfree(mem->stat.cpustat);
- else
-+ kfree(mem->stat.cpustat);
-+
-+ if (is_vmalloc_addr(mem))
- vfree(mem);
-+ else
-+ kfree(mem);
- }
-
-
-@@ -1125,6 +1157,7 @@ mem_cgroup_create(struct cgroup_subsys *
-
- if (unlikely((cont->parent) == NULL)) {
- mem = &init_mem_cgroup;
-+ mem->stat.cpustat = &init_mem_cgroup_stat_cpu[0];
- page_cgroup_cache = KMEM_CACHE(page_cgroup, SLAB_PANIC);
- } else {
- mem = mem_cgroup_alloc();