aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup_subsys.h6
-rw-r--r--include/linux/hugetlb_cgroup.h37
-rw-r--r--init/Kconfig15
-rw-r--r--mm/Makefile1
-rw-r--r--mm/hugetlb_cgroup.c120
5 files changed, 179 insertions, 0 deletions
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index 0bd390ce98b2..5b41ce079024 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -72,3 +72,9 @@ SUBSYS(net_prio)
72#endif 72#endif
73 73
74/* */ 74/* */
75
76#ifdef CONFIG_CGROUP_HUGETLB
77SUBSYS(hugetlb)
78#endif
79
80/* */
diff --git a/include/linux/hugetlb_cgroup.h b/include/linux/hugetlb_cgroup.h
new file mode 100644
index 000000000000..f19889e56b47
--- /dev/null
+++ b/include/linux/hugetlb_cgroup.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright IBM Corporation, 2012
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15#ifndef _LINUX_HUGETLB_CGROUP_H
16#define _LINUX_HUGETLB_CGROUP_H
17
18#include <linux/res_counter.h>
19
20struct hugetlb_cgroup;
21
22#ifdef CONFIG_CGROUP_HUGETLB
23static inline bool hugetlb_cgroup_disabled(void)
24{
25 if (hugetlb_subsys.disabled)
26 return true;
27 return false;
28}
29
30#else
31static inline bool hugetlb_cgroup_disabled(void)
32{
33 return true;
34}
35
36#endif /* CONFIG_MEM_RES_CTLR_HUGETLB */
37#endif
diff --git a/init/Kconfig b/init/Kconfig
index b3f55f15e107..72437760e90e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -751,6 +751,21 @@ config CGROUP_MEM_RES_CTLR_KMEM
751 the kmem extension can use it to guarantee that no group of processes 751 the kmem extension can use it to guarantee that no group of processes
752 will ever exhaust kernel resources alone. 752 will ever exhaust kernel resources alone.
753 753
754config CGROUP_HUGETLB
755 bool "HugeTLB Resource Controller for Control Groups"
756 depends on RESOURCE_COUNTERS && HUGETLB_PAGE && EXPERIMENTAL
757 default n
758 help
759 Provides a cgroup Resource Controller for HugeTLB pages.
760 When you enable this, you can put a per cgroup limit on HugeTLB usage.
761 The limit is enforced during page fault. Since HugeTLB doesn't
762 support page reclaim, enforcing the limit at page fault time implies
763 that, the application will get SIGBUS signal if it tries to access
764 HugeTLB pages beyond its limit. This requires the application to know
765 beforehand how much HugeTLB pages it would require for its use. The
766 control group is tracked in the third page lru pointer. This means
767 that we cannot use the controller with huge page less than 3 pages.
768
754config CGROUP_PERF 769config CGROUP_PERF
755 bool "Enable perf_event per-cpu per-container group (cgroup) monitoring" 770 bool "Enable perf_event per-cpu per-container group (cgroup) monitoring"
756 depends on PERF_EVENTS && CGROUPS 771 depends on PERF_EVENTS && CGROUPS
diff --git a/mm/Makefile b/mm/Makefile
index 8e81fe263c94..fd6fc1c1966c 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_MIGRATION) += migrate.o
50obj-$(CONFIG_QUICKLIST) += quicklist.o 50obj-$(CONFIG_QUICKLIST) += quicklist.o
51obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o 51obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o
52obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o 52obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
53obj-$(CONFIG_CGROUP_HUGETLB) += hugetlb_cgroup.o
53obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o 54obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
54obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o 55obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
55obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o 56obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c
new file mode 100644
index 000000000000..0d1a66e9039b
--- /dev/null
+++ b/mm/hugetlb_cgroup.c
@@ -0,0 +1,120 @@
1/*
2 *
3 * Copyright IBM Corporation, 2012
4 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 */
15
16#include <linux/cgroup.h>
17#include <linux/slab.h>
18#include <linux/hugetlb.h>
19#include <linux/hugetlb_cgroup.h>
20
21struct hugetlb_cgroup {
22 struct cgroup_subsys_state css;
23 /*
24 * the counter to account for hugepages from hugetlb.
25 */
26 struct res_counter hugepage[HUGE_MAX_HSTATE];
27};
28
29struct cgroup_subsys hugetlb_subsys __read_mostly;
30static struct hugetlb_cgroup *root_h_cgroup __read_mostly;
31
32static inline
33struct hugetlb_cgroup *hugetlb_cgroup_from_css(struct cgroup_subsys_state *s)
34{
35 return container_of(s, struct hugetlb_cgroup, css);
36}
37
38static inline
39struct hugetlb_cgroup *hugetlb_cgroup_from_cgroup(struct cgroup *cgroup)
40{
41 return hugetlb_cgroup_from_css(cgroup_subsys_state(cgroup,
42 hugetlb_subsys_id));
43}
44
45static inline
46struct hugetlb_cgroup *hugetlb_cgroup_from_task(struct task_struct *task)
47{
48 return hugetlb_cgroup_from_css(task_subsys_state(task,
49 hugetlb_subsys_id));
50}
51
52static inline bool hugetlb_cgroup_is_root(struct hugetlb_cgroup *h_cg)
53{
54 return (h_cg == root_h_cgroup);
55}
56
57static inline struct hugetlb_cgroup *parent_hugetlb_cgroup(struct cgroup *cg)
58{
59 if (!cg->parent)
60 return NULL;
61 return hugetlb_cgroup_from_cgroup(cg->parent);
62}
63
64static inline bool hugetlb_cgroup_have_usage(struct cgroup *cg)
65{
66 int idx;
67 struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cg);
68
69 for (idx = 0; idx < hugetlb_max_hstate; idx++) {
70 if ((res_counter_read_u64(&h_cg->hugepage[idx], RES_USAGE)) > 0)
71 return true;
72 }
73 return false;
74}
75
76static struct cgroup_subsys_state *hugetlb_cgroup_create(struct cgroup *cgroup)
77{
78 int idx;
79 struct cgroup *parent_cgroup;
80 struct hugetlb_cgroup *h_cgroup, *parent_h_cgroup;
81
82 h_cgroup = kzalloc(sizeof(*h_cgroup), GFP_KERNEL);
83 if (!h_cgroup)
84 return ERR_PTR(-ENOMEM);
85
86 parent_cgroup = cgroup->parent;
87 if (parent_cgroup) {
88 parent_h_cgroup = hugetlb_cgroup_from_cgroup(parent_cgroup);
89 for (idx = 0; idx < HUGE_MAX_HSTATE; idx++)
90 res_counter_init(&h_cgroup->hugepage[idx],
91 &parent_h_cgroup->hugepage[idx]);
92 } else {
93 root_h_cgroup = h_cgroup;
94 for (idx = 0; idx < HUGE_MAX_HSTATE; idx++)
95 res_counter_init(&h_cgroup->hugepage[idx], NULL);
96 }
97 return &h_cgroup->css;
98}
99
100static void hugetlb_cgroup_destroy(struct cgroup *cgroup)
101{
102 struct hugetlb_cgroup *h_cgroup;
103
104 h_cgroup = hugetlb_cgroup_from_cgroup(cgroup);
105 kfree(h_cgroup);
106}
107
108static int hugetlb_cgroup_pre_destroy(struct cgroup *cgroup)
109{
110 /* We will add the cgroup removal support in later patches */
111 return -EBUSY;
112}
113
114struct cgroup_subsys hugetlb_subsys = {
115 .name = "hugetlb",
116 .create = hugetlb_cgroup_create,
117 .pre_destroy = hugetlb_cgroup_pre_destroy,
118 .destroy = hugetlb_cgroup_destroy,
119 .subsys_id = hugetlb_subsys_id,
120};