aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2008-04-29 04:00:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:11 -0400
commit33327948782bcef89c78eb47af86b6a2df9fd4a5 (patch)
treec1045eaee1b63a6be37a09c969e2433a5c595c33 /mm
parent4a56d02e34baedbea5eb1fd558f2b856b8c7db1e (diff)
memcgroup: use vmalloc for mem_cgroup allocation
On ia64, this kmalloc() requires order-4 pages. But this is not necessary to be physically contiguous. For big mem_cgroup, vmalloc is better. For small ones, kmalloc is used. [akpm@linux-foundation.org: simplification] Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Balbir Singh <balbir@in.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c35
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
987static 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
1001static 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
986static struct cgroup_subsys_state * 1010static struct cgroup_subsys_state *
987mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) 1011mem_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
1038static int mem_cgroup_populate(struct cgroup_subsys *ss, 1061static int mem_cgroup_populate(struct cgroup_subsys *ss,