diff options
-rw-r--r-- | include/linux/page_cgroup.h | 5 | ||||
-rw-r--r-- | init/main.c | 2 | ||||
-rw-r--r-- | mm/memcontrol.c | 1 | ||||
-rw-r--r-- | mm/page_cgroup.c | 32 |
4 files changed, 32 insertions, 8 deletions
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index 0fd39f2231ec..f546ad6fc028 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h | |||
@@ -99,5 +99,10 @@ static inline struct page_cgroup *lookup_page_cgroup(struct page *page) | |||
99 | { | 99 | { |
100 | return NULL; | 100 | return NULL; |
101 | } | 101 | } |
102 | |||
103 | static inline void page_cgroup_init(void) | ||
104 | { | ||
105 | } | ||
106 | |||
102 | #endif | 107 | #endif |
103 | #endif | 108 | #endif |
diff --git a/init/main.c b/init/main.c index 3e17a3bafe60..672ae75b2059 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/key.h> | 52 | #include <linux/key.h> |
53 | #include <linux/unwind.h> | 53 | #include <linux/unwind.h> |
54 | #include <linux/buffer_head.h> | 54 | #include <linux/buffer_head.h> |
55 | #include <linux/page_cgroup.h> | ||
55 | #include <linux/debug_locks.h> | 56 | #include <linux/debug_locks.h> |
56 | #include <linux/debugobjects.h> | 57 | #include <linux/debugobjects.h> |
57 | #include <linux/lockdep.h> | 58 | #include <linux/lockdep.h> |
@@ -647,6 +648,7 @@ asmlinkage void __init start_kernel(void) | |||
647 | vmalloc_init(); | 648 | vmalloc_init(); |
648 | vfs_caches_init_early(); | 649 | vfs_caches_init_early(); |
649 | cpuset_init_early(); | 650 | cpuset_init_early(); |
651 | page_cgroup_init(); | ||
650 | mem_init(); | 652 | mem_init(); |
651 | enable_debug_pagealloc(); | 653 | enable_debug_pagealloc(); |
652 | cpu_hotplug_init(); | 654 | cpu_hotplug_init(); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index d4a92b63e98e..866dcc7eeb0c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1088,7 +1088,6 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | |||
1088 | int node; | 1088 | int node; |
1089 | 1089 | ||
1090 | if (unlikely((cont->parent) == NULL)) { | 1090 | if (unlikely((cont->parent) == NULL)) { |
1091 | page_cgroup_init(); | ||
1092 | mem = &init_mem_cgroup; | 1091 | mem = &init_mem_cgroup; |
1093 | } else { | 1092 | } else { |
1094 | mem = mem_cgroup_alloc(); | 1093 | mem = mem_cgroup_alloc(); |
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 78242b4d7edf..f59d797dc5a9 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c | |||
@@ -4,8 +4,10 @@ | |||
4 | #include <linux/bit_spinlock.h> | 4 | #include <linux/bit_spinlock.h> |
5 | #include <linux/page_cgroup.h> | 5 | #include <linux/page_cgroup.h> |
6 | #include <linux/hash.h> | 6 | #include <linux/hash.h> |
7 | #include <linux/slab.h> | ||
7 | #include <linux/memory.h> | 8 | #include <linux/memory.h> |
8 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
10 | #include <linux/cgroup.h> | ||
9 | 11 | ||
10 | static void __meminit | 12 | static void __meminit |
11 | __init_page_cgroup(struct page_cgroup *pc, unsigned long pfn) | 13 | __init_page_cgroup(struct page_cgroup *pc, unsigned long pfn) |
@@ -67,6 +69,9 @@ void __init page_cgroup_init(void) | |||
67 | 69 | ||
68 | int nid, fail; | 70 | int nid, fail; |
69 | 71 | ||
72 | if (mem_cgroup_subsys.disabled) | ||
73 | return; | ||
74 | |||
70 | for_each_online_node(nid) { | 75 | for_each_online_node(nid) { |
71 | fail = alloc_node_page_cgroup(nid); | 76 | fail = alloc_node_page_cgroup(nid); |
72 | if (fail) | 77 | if (fail) |
@@ -107,9 +112,14 @@ int __meminit init_section_page_cgroup(unsigned long pfn) | |||
107 | nid = page_to_nid(pfn_to_page(pfn)); | 112 | nid = page_to_nid(pfn_to_page(pfn)); |
108 | 113 | ||
109 | table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; | 114 | table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; |
110 | base = kmalloc_node(table_size, GFP_KERNEL, nid); | 115 | if (slab_is_available()) { |
111 | if (!base) | 116 | base = kmalloc_node(table_size, GFP_KERNEL, nid); |
112 | base = vmalloc_node(table_size, nid); | 117 | if (!base) |
118 | base = vmalloc_node(table_size, nid); | ||
119 | } else { | ||
120 | base = __alloc_bootmem_node_nopanic(NODE_DATA(nid), table_size, | ||
121 | PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); | ||
122 | } | ||
113 | 123 | ||
114 | if (!base) { | 124 | if (!base) { |
115 | printk(KERN_ERR "page cgroup allocation failure\n"); | 125 | printk(KERN_ERR "page cgroup allocation failure\n"); |
@@ -136,11 +146,16 @@ void __free_page_cgroup(unsigned long pfn) | |||
136 | if (!ms || !ms->page_cgroup) | 146 | if (!ms || !ms->page_cgroup) |
137 | return; | 147 | return; |
138 | base = ms->page_cgroup + pfn; | 148 | base = ms->page_cgroup + pfn; |
139 | ms->page_cgroup = NULL; | 149 | if (is_vmalloc_addr(base)) { |
140 | if (is_vmalloc_addr(base)) | ||
141 | vfree(base); | 150 | vfree(base); |
142 | else | 151 | ms->page_cgroup = NULL; |
143 | kfree(base); | 152 | } else { |
153 | struct page *page = virt_to_page(base); | ||
154 | if (!PageReserved(page)) { /* Is bootmem ? */ | ||
155 | kfree(base); | ||
156 | ms->page_cgroup = NULL; | ||
157 | } | ||
158 | } | ||
144 | } | 159 | } |
145 | 160 | ||
146 | int online_page_cgroup(unsigned long start_pfn, | 161 | int online_page_cgroup(unsigned long start_pfn, |
@@ -214,6 +229,9 @@ void __init page_cgroup_init(void) | |||
214 | unsigned long pfn; | 229 | unsigned long pfn; |
215 | int fail = 0; | 230 | int fail = 0; |
216 | 231 | ||
232 | if (mem_cgroup_subsys.disabled) | ||
233 | return; | ||
234 | |||
217 | for (pfn = 0; !fail && pfn < max_pfn; pfn += PAGES_PER_SECTION) { | 235 | for (pfn = 0; !fail && pfn < max_pfn; pfn += PAGES_PER_SECTION) { |
218 | if (!pfn_present(pfn)) | 236 | if (!pfn_present(pfn)) |
219 | continue; | 237 | continue; |