diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memcontrol.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c5285afe2048..15aa34b11e88 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/vmalloc.h> | ||
34 | 35 | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | 37 | ||
@@ -983,6 +984,29 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node) | |||
983 | kfree(mem->info.nodeinfo[node]); | 984 | kfree(mem->info.nodeinfo[node]); |
984 | } | 985 | } |
985 | 986 | ||
987 | static struct mem_cgroup *mem_cgroup_alloc(void) | ||
988 | { | ||
989 | struct mem_cgroup *mem; | ||
990 | |||
991 | if (sizeof(*mem) < PAGE_SIZE) | ||
992 | mem = kmalloc(sizeof(*mem), GFP_KERNEL); | ||
993 | else | ||
994 | mem = vmalloc(sizeof(*mem)); | ||
995 | |||
996 | if (mem) | ||
997 | memset(mem, 0, sizeof(*mem)); | ||
998 | return mem; | ||
999 | } | ||
1000 | |||
1001 | static void mem_cgroup_free(struct mem_cgroup *mem) | ||
1002 | { | ||
1003 | if (sizeof(*mem) < PAGE_SIZE) | ||
1004 | kfree(mem); | ||
1005 | else | ||
1006 | vfree(mem); | ||
1007 | } | ||
1008 | |||
1009 | |||
986 | static struct cgroup_subsys_state * | 1010 | static struct cgroup_subsys_state * |
987 | mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | 1011 | mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) |
988 | { | 1012 | { |
@@ -993,12 +1017,11 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | |||
993 | mem = &init_mem_cgroup; | 1017 | mem = &init_mem_cgroup; |
994 | page_cgroup_cache = KMEM_CACHE(page_cgroup, SLAB_PANIC); | 1018 | page_cgroup_cache = KMEM_CACHE(page_cgroup, SLAB_PANIC); |
995 | } else { | 1019 | } else { |
996 | mem = kzalloc(sizeof(struct mem_cgroup), GFP_KERNEL); | 1020 | mem = mem_cgroup_alloc(); |
1021 | if (!mem) | ||
1022 | return ERR_PTR(-ENOMEM); | ||
997 | } | 1023 | } |
998 | 1024 | ||
999 | if (mem == NULL) | ||
1000 | return ERR_PTR(-ENOMEM); | ||
1001 | |||
1002 | res_counter_init(&mem->res); | 1025 | res_counter_init(&mem->res); |
1003 | 1026 | ||
1004 | memset(&mem->info, 0, sizeof(mem->info)); | 1027 | memset(&mem->info, 0, sizeof(mem->info)); |
@@ -1012,7 +1035,7 @@ free_out: | |||
1012 | for_each_node_state(node, N_POSSIBLE) | 1035 | for_each_node_state(node, N_POSSIBLE) |
1013 | free_mem_cgroup_per_zone_info(mem, node); | 1036 | free_mem_cgroup_per_zone_info(mem, node); |
1014 | if (cont->parent != NULL) | 1037 | if (cont->parent != NULL) |
1015 | kfree(mem); | 1038 | mem_cgroup_free(mem); |
1016 | return ERR_PTR(-ENOMEM); | 1039 | return ERR_PTR(-ENOMEM); |
1017 | } | 1040 | } |
1018 | 1041 | ||
@@ -1032,7 +1055,7 @@ static void mem_cgroup_destroy(struct cgroup_subsys *ss, | |||
1032 | for_each_node_state(node, N_POSSIBLE) | 1055 | for_each_node_state(node, N_POSSIBLE) |
1033 | free_mem_cgroup_per_zone_info(mem, node); | 1056 | free_mem_cgroup_per_zone_info(mem, node); |
1034 | 1057 | ||
1035 | kfree(mem_cgroup_from_cont(cont)); | 1058 | mem_cgroup_free(mem_cgroup_from_cont(cont)); |
1036 | } | 1059 | } |
1037 | 1060 | ||
1038 | static int mem_cgroup_populate(struct cgroup_subsys *ss, | 1061 | static int mem_cgroup_populate(struct cgroup_subsys *ss, |