aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup_subsys.h5
-rw-r--r--include/linux/memcontrol.h21
-rw-r--r--init/Kconfig7
-rw-r--r--mm/Makefile1
-rw-r--r--mm/memcontrol.c127
5 files changed, 161 insertions, 0 deletions
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index 9ec43186ba80..228235c5ae53 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -37,3 +37,8 @@ SUBSYS(cpuacct)
37 37
38/* */ 38/* */
39 39
40#ifdef CONFIG_CGROUP_MEM_CONT
41SUBSYS(mem_cgroup)
42#endif
43
44/* */
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
new file mode 100644
index 000000000000..3f121b27677a
--- /dev/null
+++ b/include/linux/memcontrol.h
@@ -0,0 +1,21 @@
1/* memcontrol.h - Memory Controller
2 *
3 * Copyright IBM Corporation, 2007
4 * Author Balbir Singh <balbir@linux.vnet.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _LINUX_MEMCONTROL_H
18#define _LINUX_MEMCONTROL_H
19
20#endif /* _LINUX_MEMCONTROL_H */
21
diff --git a/init/Kconfig b/init/Kconfig
index d372bd616b0c..95ac2657b0f4 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -397,6 +397,13 @@ config SYSFS_DEPRECATED
397 If you are using a distro that was released in 2006 or later, 397 If you are using a distro that was released in 2006 or later,
398 it should be safe to say N here. 398 it should be safe to say N here.
399 399
400config CGROUP_MEM_CONT
401 bool "Memory controller for cgroups"
402 depends on CGROUPS && RESOURCE_COUNTERS
403 help
404 Provides a memory controller that manages both page cache and
405 RSS memory.
406
400config PROC_PID_CPUSET 407config PROC_PID_CPUSET
401 bool "Include legacy /proc/<pid>/cpuset file" 408 bool "Include legacy /proc/<pid>/cpuset file"
402 depends on CPUSETS 409 depends on CPUSETS
diff --git a/mm/Makefile b/mm/Makefile
index 4af5dff37277..9f117bab5322 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -32,4 +32,5 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o
32obj-$(CONFIG_MIGRATION) += migrate.o 32obj-$(CONFIG_MIGRATION) += migrate.o
33obj-$(CONFIG_SMP) += allocpercpu.o 33obj-$(CONFIG_SMP) += allocpercpu.o
34obj-$(CONFIG_QUICKLIST) += quicklist.o 34obj-$(CONFIG_QUICKLIST) += quicklist.o
35obj-$(CONFIG_CGROUP_MEM_CONT) += memcontrol.o
35 36
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
new file mode 100644
index 000000000000..80e48cd9d0c7
--- /dev/null
+++ b/mm/memcontrol.c
@@ -0,0 +1,127 @@
1/* memcontrol.c - Memory Controller
2 *
3 * Copyright IBM Corporation, 2007
4 * Author Balbir Singh <balbir@linux.vnet.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/res_counter.h>
18#include <linux/memcontrol.h>
19#include <linux/cgroup.h>
20
21struct cgroup_subsys mem_cgroup_subsys;
22
23/*
24 * The memory controller data structure. The memory controller controls both
25 * page cache and RSS per cgroup. We would eventually like to provide
26 * statistics based on the statistics developed by Rik Van Riel for clock-pro,
27 * to help the administrator determine what knobs to tune.
28 *
29 * TODO: Add a water mark for the memory controller. Reclaim will begin when
30 * we hit the water mark.
31 */
32struct mem_cgroup {
33 struct cgroup_subsys_state css;
34 /*
35 * the counter to account for memory usage
36 */
37 struct res_counter res;
38};
39
40/*
41 * A page_cgroup page is associated with every page descriptor. The
42 * page_cgroup helps us identify information about the cgroup
43 */
44struct page_cgroup {
45 struct list_head lru; /* per cgroup LRU list */
46 struct page *page;
47 struct mem_cgroup *mem_cgroup;
48};
49
50
51static inline
52struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
53{
54 return container_of(cgroup_subsys_state(cont,
55 mem_cgroup_subsys_id), struct mem_cgroup,
56 css);
57}
58
59static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft,
60 struct file *file, char __user *userbuf, size_t nbytes,
61 loff_t *ppos)
62{
63 return res_counter_read(&mem_cgroup_from_cont(cont)->res,
64 cft->private, userbuf, nbytes, ppos);
65}
66
67static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
68 struct file *file, const char __user *userbuf,
69 size_t nbytes, loff_t *ppos)
70{
71 return res_counter_write(&mem_cgroup_from_cont(cont)->res,
72 cft->private, userbuf, nbytes, ppos);
73}
74
75static struct cftype mem_cgroup_files[] = {
76 {
77 .name = "usage",
78 .private = RES_USAGE,
79 .read = mem_cgroup_read,
80 },
81 {
82 .name = "limit",
83 .private = RES_LIMIT,
84 .write = mem_cgroup_write,
85 .read = mem_cgroup_read,
86 },
87 {
88 .name = "failcnt",
89 .private = RES_FAILCNT,
90 .read = mem_cgroup_read,
91 },
92};
93
94static struct cgroup_subsys_state *
95mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
96{
97 struct mem_cgroup *mem;
98
99 mem = kzalloc(sizeof(struct mem_cgroup), GFP_KERNEL);
100 if (!mem)
101 return -ENOMEM;
102
103 res_counter_init(&mem->res);
104 return &mem->css;
105}
106
107static void mem_cgroup_destroy(struct cgroup_subsys *ss,
108 struct cgroup *cont)
109{
110 kfree(mem_cgroup_from_cont(cont));
111}
112
113static int mem_cgroup_populate(struct cgroup_subsys *ss,
114 struct cgroup *cont)
115{
116 return cgroup_add_files(cont, ss, mem_cgroup_files,
117 ARRAY_SIZE(mem_cgroup_files));
118}
119
120struct cgroup_subsys mem_cgroup_subsys = {
121 .name = "memory",
122 .subsys_id = mem_cgroup_subsys_id,
123 .create = mem_cgroup_create,
124 .destroy = mem_cgroup_destroy,
125 .populate = mem_cgroup_populate,
126 .early_init = 0,
127};