diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 21:25:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 21:25:03 -0400 |
commit | 32dad03d164206ea886885d0740284ba215b0970 (patch) | |
tree | 5fd89fe27295bfbe47dce5f274aa645099741a71 /mm | |
parent | 357397a14117f0c2eeafcac06a1f8412a02aa6af (diff) | |
parent | d1625964da51bda61306ad3ec45307a799c21f08 (diff) |
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo:
"A lot of activities on the cgroup front. Most changes aren't visible
to userland at all at this point and are laying foundation for the
planned unified hierarchy.
- The biggest change is decoupling the lifetime management of css
(cgroup_subsys_state) from that of cgroup's. Because controllers
(cpu, memory, block and so on) will need to be dynamically enabled
and disabled, css which is the association point between a cgroup
and a controller may come and go dynamically across the lifetime of
a cgroup. Till now, css's were created when the associated cgroup
was created and stayed till the cgroup got destroyed.
Assumptions around this tight coupling permeated through cgroup
core and controllers. These assumptions are gradually removed,
which consists bulk of patches, and css destruction path is
completely decoupled from cgroup destruction path. Note that
decoupling of creation path is relatively easy on top of these
changes and the patchset is pending for the next window.
- cgroup has its own event mechanism cgroup.event_control, which is
only used by memcg. It is overly complex trying to achieve high
flexibility whose benefits seem dubious at best. Going forward,
new events will simply generate file modified event and the
existing mechanism is being made specific to memcg. This pull
request contains prepatory patches for such change.
- Various fixes and cleanups"
Fixed up conflict in kernel/cgroup.c as per Tejun.
* 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (69 commits)
cgroup: fix cgroup_css() invocation in css_from_id()
cgroup: make cgroup_write_event_control() use css_from_dir() instead of __d_cgrp()
cgroup: make cgroup_event hold onto cgroup_subsys_state instead of cgroup
cgroup: implement CFTYPE_NO_PREFIX
cgroup: make cgroup_css() take cgroup_subsys * instead and allow NULL subsys
cgroup: rename cgroup_css_from_dir() to css_from_dir() and update its syntax
cgroup: fix cgroup_write_event_control()
cgroup: fix subsystem file accesses on the root cgroup
cgroup: change cgroup_from_id() to css_from_id()
cgroup: use css_get() in cgroup_create() to check CSS_ROOT
cpuset: remove an unncessary forward declaration
cgroup: RCU protect each cgroup_subsys_state release
cgroup: move subsys file removal to kill_css()
cgroup: factor out kill_css()
cgroup: decouple cgroup_subsys_state destruction from cgroup destruction
cgroup: replace cgroup->css_kill_cnt with ->nr_css
cgroup: bounce cgroup_subsys_state ref kill confirmation to a work item
cgroup: move cgroup->subsys[] assignment to online_css()
cgroup: reorganize css init / exit paths
cgroup: add __rcu modifier to cgroup->subsys[]
...
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb_cgroup.c | 69 | ||||
-rw-r--r-- | mm/memcontrol.c | 223 | ||||
-rw-r--r-- | mm/vmpressure.c | 25 |
3 files changed, 137 insertions, 180 deletions
diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c index 9cea7de22ffb..bda8e44f6fde 100644 --- a/mm/hugetlb_cgroup.c +++ b/mm/hugetlb_cgroup.c | |||
@@ -36,21 +36,13 @@ static struct hugetlb_cgroup *root_h_cgroup __read_mostly; | |||
36 | static inline | 36 | static inline |
37 | struct hugetlb_cgroup *hugetlb_cgroup_from_css(struct cgroup_subsys_state *s) | 37 | struct hugetlb_cgroup *hugetlb_cgroup_from_css(struct cgroup_subsys_state *s) |
38 | { | 38 | { |
39 | return container_of(s, struct hugetlb_cgroup, css); | 39 | return s ? container_of(s, struct hugetlb_cgroup, css) : NULL; |
40 | } | ||
41 | |||
42 | static inline | ||
43 | struct hugetlb_cgroup *hugetlb_cgroup_from_cgroup(struct cgroup *cgroup) | ||
44 | { | ||
45 | return hugetlb_cgroup_from_css(cgroup_subsys_state(cgroup, | ||
46 | hugetlb_subsys_id)); | ||
47 | } | 40 | } |
48 | 41 | ||
49 | static inline | 42 | static inline |
50 | struct hugetlb_cgroup *hugetlb_cgroup_from_task(struct task_struct *task) | 43 | struct hugetlb_cgroup *hugetlb_cgroup_from_task(struct task_struct *task) |
51 | { | 44 | { |
52 | return hugetlb_cgroup_from_css(task_subsys_state(task, | 45 | return hugetlb_cgroup_from_css(task_css(task, hugetlb_subsys_id)); |
53 | hugetlb_subsys_id)); | ||
54 | } | 46 | } |
55 | 47 | ||
56 | static inline bool hugetlb_cgroup_is_root(struct hugetlb_cgroup *h_cg) | 48 | static inline bool hugetlb_cgroup_is_root(struct hugetlb_cgroup *h_cg) |
@@ -58,17 +50,15 @@ static inline bool hugetlb_cgroup_is_root(struct hugetlb_cgroup *h_cg) | |||
58 | return (h_cg == root_h_cgroup); | 50 | return (h_cg == root_h_cgroup); |
59 | } | 51 | } |
60 | 52 | ||
61 | static inline struct hugetlb_cgroup *parent_hugetlb_cgroup(struct cgroup *cg) | 53 | static inline struct hugetlb_cgroup * |
54 | parent_hugetlb_cgroup(struct hugetlb_cgroup *h_cg) | ||
62 | { | 55 | { |
63 | if (!cg->parent) | 56 | return hugetlb_cgroup_from_css(css_parent(&h_cg->css)); |
64 | return NULL; | ||
65 | return hugetlb_cgroup_from_cgroup(cg->parent); | ||
66 | } | 57 | } |
67 | 58 | ||
68 | static inline bool hugetlb_cgroup_have_usage(struct cgroup *cg) | 59 | static inline bool hugetlb_cgroup_have_usage(struct hugetlb_cgroup *h_cg) |
69 | { | 60 | { |
70 | int idx; | 61 | int idx; |
71 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cg); | ||
72 | 62 | ||
73 | for (idx = 0; idx < hugetlb_max_hstate; idx++) { | 63 | for (idx = 0; idx < hugetlb_max_hstate; idx++) { |
74 | if ((res_counter_read_u64(&h_cg->hugepage[idx], RES_USAGE)) > 0) | 64 | if ((res_counter_read_u64(&h_cg->hugepage[idx], RES_USAGE)) > 0) |
@@ -77,19 +67,18 @@ static inline bool hugetlb_cgroup_have_usage(struct cgroup *cg) | |||
77 | return false; | 67 | return false; |
78 | } | 68 | } |
79 | 69 | ||
80 | static struct cgroup_subsys_state *hugetlb_cgroup_css_alloc(struct cgroup *cgroup) | 70 | static struct cgroup_subsys_state * |
71 | hugetlb_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) | ||
81 | { | 72 | { |
73 | struct hugetlb_cgroup *parent_h_cgroup = hugetlb_cgroup_from_css(parent_css); | ||
74 | struct hugetlb_cgroup *h_cgroup; | ||
82 | int idx; | 75 | int idx; |
83 | struct cgroup *parent_cgroup; | ||
84 | struct hugetlb_cgroup *h_cgroup, *parent_h_cgroup; | ||
85 | 76 | ||
86 | h_cgroup = kzalloc(sizeof(*h_cgroup), GFP_KERNEL); | 77 | h_cgroup = kzalloc(sizeof(*h_cgroup), GFP_KERNEL); |
87 | if (!h_cgroup) | 78 | if (!h_cgroup) |
88 | return ERR_PTR(-ENOMEM); | 79 | return ERR_PTR(-ENOMEM); |
89 | 80 | ||
90 | parent_cgroup = cgroup->parent; | 81 | if (parent_h_cgroup) { |
91 | if (parent_cgroup) { | ||
92 | parent_h_cgroup = hugetlb_cgroup_from_cgroup(parent_cgroup); | ||
93 | for (idx = 0; idx < HUGE_MAX_HSTATE; idx++) | 82 | for (idx = 0; idx < HUGE_MAX_HSTATE; idx++) |
94 | res_counter_init(&h_cgroup->hugepage[idx], | 83 | res_counter_init(&h_cgroup->hugepage[idx], |
95 | &parent_h_cgroup->hugepage[idx]); | 84 | &parent_h_cgroup->hugepage[idx]); |
@@ -101,11 +90,11 @@ static struct cgroup_subsys_state *hugetlb_cgroup_css_alloc(struct cgroup *cgrou | |||
101 | return &h_cgroup->css; | 90 | return &h_cgroup->css; |
102 | } | 91 | } |
103 | 92 | ||
104 | static void hugetlb_cgroup_css_free(struct cgroup *cgroup) | 93 | static void hugetlb_cgroup_css_free(struct cgroup_subsys_state *css) |
105 | { | 94 | { |
106 | struct hugetlb_cgroup *h_cgroup; | 95 | struct hugetlb_cgroup *h_cgroup; |
107 | 96 | ||
108 | h_cgroup = hugetlb_cgroup_from_cgroup(cgroup); | 97 | h_cgroup = hugetlb_cgroup_from_css(css); |
109 | kfree(h_cgroup); | 98 | kfree(h_cgroup); |
110 | } | 99 | } |
111 | 100 | ||
@@ -117,15 +106,14 @@ static void hugetlb_cgroup_css_free(struct cgroup *cgroup) | |||
117 | * page reference and test for page active here. This function | 106 | * page reference and test for page active here. This function |
118 | * cannot fail. | 107 | * cannot fail. |
119 | */ | 108 | */ |
120 | static void hugetlb_cgroup_move_parent(int idx, struct cgroup *cgroup, | 109 | static void hugetlb_cgroup_move_parent(int idx, struct hugetlb_cgroup *h_cg, |
121 | struct page *page) | 110 | struct page *page) |
122 | { | 111 | { |
123 | int csize; | 112 | int csize; |
124 | struct res_counter *counter; | 113 | struct res_counter *counter; |
125 | struct res_counter *fail_res; | 114 | struct res_counter *fail_res; |
126 | struct hugetlb_cgroup *page_hcg; | 115 | struct hugetlb_cgroup *page_hcg; |
127 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cgroup); | 116 | struct hugetlb_cgroup *parent = parent_hugetlb_cgroup(h_cg); |
128 | struct hugetlb_cgroup *parent = parent_hugetlb_cgroup(cgroup); | ||
129 | 117 | ||
130 | page_hcg = hugetlb_cgroup_from_page(page); | 118 | page_hcg = hugetlb_cgroup_from_page(page); |
131 | /* | 119 | /* |
@@ -155,8 +143,9 @@ out: | |||
155 | * Force the hugetlb cgroup to empty the hugetlb resources by moving them to | 143 | * Force the hugetlb cgroup to empty the hugetlb resources by moving them to |
156 | * the parent cgroup. | 144 | * the parent cgroup. |
157 | */ | 145 | */ |
158 | static void hugetlb_cgroup_css_offline(struct cgroup *cgroup) | 146 | static void hugetlb_cgroup_css_offline(struct cgroup_subsys_state *css) |
159 | { | 147 | { |
148 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css); | ||
160 | struct hstate *h; | 149 | struct hstate *h; |
161 | struct page *page; | 150 | struct page *page; |
162 | int idx = 0; | 151 | int idx = 0; |
@@ -165,13 +154,13 @@ static void hugetlb_cgroup_css_offline(struct cgroup *cgroup) | |||
165 | for_each_hstate(h) { | 154 | for_each_hstate(h) { |
166 | spin_lock(&hugetlb_lock); | 155 | spin_lock(&hugetlb_lock); |
167 | list_for_each_entry(page, &h->hugepage_activelist, lru) | 156 | list_for_each_entry(page, &h->hugepage_activelist, lru) |
168 | hugetlb_cgroup_move_parent(idx, cgroup, page); | 157 | hugetlb_cgroup_move_parent(idx, h_cg, page); |
169 | 158 | ||
170 | spin_unlock(&hugetlb_lock); | 159 | spin_unlock(&hugetlb_lock); |
171 | idx++; | 160 | idx++; |
172 | } | 161 | } |
173 | cond_resched(); | 162 | cond_resched(); |
174 | } while (hugetlb_cgroup_have_usage(cgroup)); | 163 | } while (hugetlb_cgroup_have_usage(h_cg)); |
175 | } | 164 | } |
176 | 165 | ||
177 | int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, | 166 | int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, |
@@ -253,14 +242,15 @@ void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, | |||
253 | return; | 242 | return; |
254 | } | 243 | } |
255 | 244 | ||
256 | static ssize_t hugetlb_cgroup_read(struct cgroup *cgroup, struct cftype *cft, | 245 | static ssize_t hugetlb_cgroup_read(struct cgroup_subsys_state *css, |
257 | struct file *file, char __user *buf, | 246 | struct cftype *cft, struct file *file, |
258 | size_t nbytes, loff_t *ppos) | 247 | char __user *buf, size_t nbytes, |
248 | loff_t *ppos) | ||
259 | { | 249 | { |
260 | u64 val; | 250 | u64 val; |
261 | char str[64]; | 251 | char str[64]; |
262 | int idx, name, len; | 252 | int idx, name, len; |
263 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cgroup); | 253 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css); |
264 | 254 | ||
265 | idx = MEMFILE_IDX(cft->private); | 255 | idx = MEMFILE_IDX(cft->private); |
266 | name = MEMFILE_ATTR(cft->private); | 256 | name = MEMFILE_ATTR(cft->private); |
@@ -270,12 +260,12 @@ static ssize_t hugetlb_cgroup_read(struct cgroup *cgroup, struct cftype *cft, | |||
270 | return simple_read_from_buffer(buf, nbytes, ppos, str, len); | 260 | return simple_read_from_buffer(buf, nbytes, ppos, str, len); |
271 | } | 261 | } |
272 | 262 | ||
273 | static int hugetlb_cgroup_write(struct cgroup *cgroup, struct cftype *cft, | 263 | static int hugetlb_cgroup_write(struct cgroup_subsys_state *css, |
274 | const char *buffer) | 264 | struct cftype *cft, const char *buffer) |
275 | { | 265 | { |
276 | int idx, name, ret; | 266 | int idx, name, ret; |
277 | unsigned long long val; | 267 | unsigned long long val; |
278 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cgroup); | 268 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css); |
279 | 269 | ||
280 | idx = MEMFILE_IDX(cft->private); | 270 | idx = MEMFILE_IDX(cft->private); |
281 | name = MEMFILE_ATTR(cft->private); | 271 | name = MEMFILE_ATTR(cft->private); |
@@ -300,10 +290,11 @@ static int hugetlb_cgroup_write(struct cgroup *cgroup, struct cftype *cft, | |||
300 | return ret; | 290 | return ret; |
301 | } | 291 | } |
302 | 292 | ||
303 | static int hugetlb_cgroup_reset(struct cgroup *cgroup, unsigned int event) | 293 | static int hugetlb_cgroup_reset(struct cgroup_subsys_state *css, |
294 | unsigned int event) | ||
304 | { | 295 | { |
305 | int idx, name, ret = 0; | 296 | int idx, name, ret = 0; |
306 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cgroup); | 297 | struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css); |
307 | 298 | ||
308 | idx = MEMFILE_IDX(event); | 299 | idx = MEMFILE_IDX(event); |
309 | name = MEMFILE_ATTR(event); | 300 | name = MEMFILE_ATTR(event); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 0878ff7c26a9..3b83957b6439 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -483,10 +483,9 @@ enum res_type { | |||
483 | */ | 483 | */ |
484 | static DEFINE_MUTEX(memcg_create_mutex); | 484 | static DEFINE_MUTEX(memcg_create_mutex); |
485 | 485 | ||
486 | static inline | ||
487 | struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *s) | 486 | struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *s) |
488 | { | 487 | { |
489 | return container_of(s, struct mem_cgroup, css); | 488 | return s ? container_of(s, struct mem_cgroup, css) : NULL; |
490 | } | 489 | } |
491 | 490 | ||
492 | /* Some nice accessors for the vmpressure. */ | 491 | /* Some nice accessors for the vmpressure. */ |
@@ -1035,12 +1034,6 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page) | |||
1035 | preempt_enable(); | 1034 | preempt_enable(); |
1036 | } | 1035 | } |
1037 | 1036 | ||
1038 | struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) | ||
1039 | { | ||
1040 | return mem_cgroup_from_css( | ||
1041 | cgroup_subsys_state(cont, mem_cgroup_subsys_id)); | ||
1042 | } | ||
1043 | |||
1044 | struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) | 1037 | struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) |
1045 | { | 1038 | { |
1046 | /* | 1039 | /* |
@@ -1051,7 +1044,7 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) | |||
1051 | if (unlikely(!p)) | 1044 | if (unlikely(!p)) |
1052 | return NULL; | 1045 | return NULL; |
1053 | 1046 | ||
1054 | return mem_cgroup_from_css(task_subsys_state(p, mem_cgroup_subsys_id)); | 1047 | return mem_cgroup_from_css(task_css(p, mem_cgroup_subsys_id)); |
1055 | } | 1048 | } |
1056 | 1049 | ||
1057 | struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) | 1050 | struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) |
@@ -1084,20 +1077,11 @@ struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) | |||
1084 | static struct mem_cgroup *__mem_cgroup_iter_next(struct mem_cgroup *root, | 1077 | static struct mem_cgroup *__mem_cgroup_iter_next(struct mem_cgroup *root, |
1085 | struct mem_cgroup *last_visited) | 1078 | struct mem_cgroup *last_visited) |
1086 | { | 1079 | { |
1087 | struct cgroup *prev_cgroup, *next_cgroup; | 1080 | struct cgroup_subsys_state *prev_css, *next_css; |
1088 | 1081 | ||
1089 | /* | 1082 | prev_css = last_visited ? &last_visited->css : NULL; |
1090 | * Root is not visited by cgroup iterators so it needs an | ||
1091 | * explicit visit. | ||
1092 | */ | ||
1093 | if (!last_visited) | ||
1094 | return root; | ||
1095 | |||
1096 | prev_cgroup = (last_visited == root) ? NULL | ||
1097 | : last_visited->css.cgroup; | ||
1098 | skip_node: | 1083 | skip_node: |
1099 | next_cgroup = cgroup_next_descendant_pre( | 1084 | next_css = css_next_descendant_pre(prev_css, &root->css); |
1100 | prev_cgroup, root->css.cgroup); | ||
1101 | 1085 | ||
1102 | /* | 1086 | /* |
1103 | * Even if we found a group we have to make sure it is | 1087 | * Even if we found a group we have to make sure it is |
@@ -1106,13 +1090,13 @@ skip_node: | |||
1106 | * last_visited css is safe to use because it is | 1090 | * last_visited css is safe to use because it is |
1107 | * protected by css_get and the tree walk is rcu safe. | 1091 | * protected by css_get and the tree walk is rcu safe. |
1108 | */ | 1092 | */ |
1109 | if (next_cgroup) { | 1093 | if (next_css) { |
1110 | struct mem_cgroup *mem = mem_cgroup_from_cont( | 1094 | struct mem_cgroup *mem = mem_cgroup_from_css(next_css); |
1111 | next_cgroup); | 1095 | |
1112 | if (css_tryget(&mem->css)) | 1096 | if (css_tryget(&mem->css)) |
1113 | return mem; | 1097 | return mem; |
1114 | else { | 1098 | else { |
1115 | prev_cgroup = next_cgroup; | 1099 | prev_css = next_css; |
1116 | goto skip_node; | 1100 | goto skip_node; |
1117 | } | 1101 | } |
1118 | } | 1102 | } |
@@ -1525,10 +1509,8 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg) | |||
1525 | 1509 | ||
1526 | int mem_cgroup_swappiness(struct mem_cgroup *memcg) | 1510 | int mem_cgroup_swappiness(struct mem_cgroup *memcg) |
1527 | { | 1511 | { |
1528 | struct cgroup *cgrp = memcg->css.cgroup; | ||
1529 | |||
1530 | /* root ? */ | 1512 | /* root ? */ |
1531 | if (cgrp->parent == NULL) | 1513 | if (!css_parent(&memcg->css)) |
1532 | return vm_swappiness; | 1514 | return vm_swappiness; |
1533 | 1515 | ||
1534 | return memcg->swappiness; | 1516 | return memcg->swappiness; |
@@ -1805,12 +1787,11 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, | |||
1805 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL); | 1787 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL); |
1806 | totalpages = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1; | 1788 | totalpages = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1; |
1807 | for_each_mem_cgroup_tree(iter, memcg) { | 1789 | for_each_mem_cgroup_tree(iter, memcg) { |
1808 | struct cgroup *cgroup = iter->css.cgroup; | 1790 | struct css_task_iter it; |
1809 | struct cgroup_iter it; | ||
1810 | struct task_struct *task; | 1791 | struct task_struct *task; |
1811 | 1792 | ||
1812 | cgroup_iter_start(cgroup, &it); | 1793 | css_task_iter_start(&iter->css, &it); |
1813 | while ((task = cgroup_iter_next(cgroup, &it))) { | 1794 | while ((task = css_task_iter_next(&it))) { |
1814 | switch (oom_scan_process_thread(task, totalpages, NULL, | 1795 | switch (oom_scan_process_thread(task, totalpages, NULL, |
1815 | false)) { | 1796 | false)) { |
1816 | case OOM_SCAN_SELECT: | 1797 | case OOM_SCAN_SELECT: |
@@ -1823,7 +1804,7 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, | |||
1823 | case OOM_SCAN_CONTINUE: | 1804 | case OOM_SCAN_CONTINUE: |
1824 | continue; | 1805 | continue; |
1825 | case OOM_SCAN_ABORT: | 1806 | case OOM_SCAN_ABORT: |
1826 | cgroup_iter_end(cgroup, &it); | 1807 | css_task_iter_end(&it); |
1827 | mem_cgroup_iter_break(memcg, iter); | 1808 | mem_cgroup_iter_break(memcg, iter); |
1828 | if (chosen) | 1809 | if (chosen) |
1829 | put_task_struct(chosen); | 1810 | put_task_struct(chosen); |
@@ -1840,7 +1821,7 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, | |||
1840 | get_task_struct(chosen); | 1821 | get_task_struct(chosen); |
1841 | } | 1822 | } |
1842 | } | 1823 | } |
1843 | cgroup_iter_end(cgroup, &it); | 1824 | css_task_iter_end(&it); |
1844 | } | 1825 | } |
1845 | 1826 | ||
1846 | if (!chosen) | 1827 | if (!chosen) |
@@ -2954,10 +2935,10 @@ static struct kmem_cache *memcg_params_to_cache(struct memcg_cache_params *p) | |||
2954 | } | 2935 | } |
2955 | 2936 | ||
2956 | #ifdef CONFIG_SLABINFO | 2937 | #ifdef CONFIG_SLABINFO |
2957 | static int mem_cgroup_slabinfo_read(struct cgroup *cont, struct cftype *cft, | 2938 | static int mem_cgroup_slabinfo_read(struct cgroup_subsys_state *css, |
2958 | struct seq_file *m) | 2939 | struct cftype *cft, struct seq_file *m) |
2959 | { | 2940 | { |
2960 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 2941 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
2961 | struct memcg_cache_params *params; | 2942 | struct memcg_cache_params *params; |
2962 | 2943 | ||
2963 | if (!memcg_can_account_kmem(memcg)) | 2944 | if (!memcg_can_account_kmem(memcg)) |
@@ -4943,10 +4924,10 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg) | |||
4943 | */ | 4924 | */ |
4944 | static inline bool __memcg_has_children(struct mem_cgroup *memcg) | 4925 | static inline bool __memcg_has_children(struct mem_cgroup *memcg) |
4945 | { | 4926 | { |
4946 | struct cgroup *pos; | 4927 | struct cgroup_subsys_state *pos; |
4947 | 4928 | ||
4948 | /* bounce at first found */ | 4929 | /* bounce at first found */ |
4949 | cgroup_for_each_child(pos, memcg->css.cgroup) | 4930 | css_for_each_child(pos, &memcg->css) |
4950 | return true; | 4931 | return true; |
4951 | return false; | 4932 | return false; |
4952 | } | 4933 | } |
@@ -5002,9 +4983,10 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg) | |||
5002 | return 0; | 4983 | return 0; |
5003 | } | 4984 | } |
5004 | 4985 | ||
5005 | static int mem_cgroup_force_empty_write(struct cgroup *cont, unsigned int event) | 4986 | static int mem_cgroup_force_empty_write(struct cgroup_subsys_state *css, |
4987 | unsigned int event) | ||
5006 | { | 4988 | { |
5007 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 4989 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5008 | int ret; | 4990 | int ret; |
5009 | 4991 | ||
5010 | if (mem_cgroup_is_root(memcg)) | 4992 | if (mem_cgroup_is_root(memcg)) |
@@ -5017,21 +4999,18 @@ static int mem_cgroup_force_empty_write(struct cgroup *cont, unsigned int event) | |||
5017 | } | 4999 | } |
5018 | 5000 | ||
5019 | 5001 | ||
5020 | static u64 mem_cgroup_hierarchy_read(struct cgroup *cont, struct cftype *cft) | 5002 | static u64 mem_cgroup_hierarchy_read(struct cgroup_subsys_state *css, |
5003 | struct cftype *cft) | ||
5021 | { | 5004 | { |
5022 | return mem_cgroup_from_cont(cont)->use_hierarchy; | 5005 | return mem_cgroup_from_css(css)->use_hierarchy; |
5023 | } | 5006 | } |
5024 | 5007 | ||
5025 | static int mem_cgroup_hierarchy_write(struct cgroup *cont, struct cftype *cft, | 5008 | static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css, |
5026 | u64 val) | 5009 | struct cftype *cft, u64 val) |
5027 | { | 5010 | { |
5028 | int retval = 0; | 5011 | int retval = 0; |
5029 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5012 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5030 | struct cgroup *parent = cont->parent; | 5013 | struct mem_cgroup *parent_memcg = mem_cgroup_from_css(css_parent(&memcg->css)); |
5031 | struct mem_cgroup *parent_memcg = NULL; | ||
5032 | |||
5033 | if (parent) | ||
5034 | parent_memcg = mem_cgroup_from_cont(parent); | ||
5035 | 5014 | ||
5036 | mutex_lock(&memcg_create_mutex); | 5015 | mutex_lock(&memcg_create_mutex); |
5037 | 5016 | ||
@@ -5101,11 +5080,11 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap) | |||
5101 | return val << PAGE_SHIFT; | 5080 | return val << PAGE_SHIFT; |
5102 | } | 5081 | } |
5103 | 5082 | ||
5104 | static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft, | 5083 | static ssize_t mem_cgroup_read(struct cgroup_subsys_state *css, |
5105 | struct file *file, char __user *buf, | 5084 | struct cftype *cft, struct file *file, |
5106 | size_t nbytes, loff_t *ppos) | 5085 | char __user *buf, size_t nbytes, loff_t *ppos) |
5107 | { | 5086 | { |
5108 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5087 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5109 | char str[64]; | 5088 | char str[64]; |
5110 | u64 val; | 5089 | u64 val; |
5111 | int name, len; | 5090 | int name, len; |
@@ -5138,11 +5117,11 @@ static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft, | |||
5138 | return simple_read_from_buffer(buf, nbytes, ppos, str, len); | 5117 | return simple_read_from_buffer(buf, nbytes, ppos, str, len); |
5139 | } | 5118 | } |
5140 | 5119 | ||
5141 | static int memcg_update_kmem_limit(struct cgroup *cont, u64 val) | 5120 | static int memcg_update_kmem_limit(struct cgroup_subsys_state *css, u64 val) |
5142 | { | 5121 | { |
5143 | int ret = -EINVAL; | 5122 | int ret = -EINVAL; |
5144 | #ifdef CONFIG_MEMCG_KMEM | 5123 | #ifdef CONFIG_MEMCG_KMEM |
5145 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5124 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5146 | /* | 5125 | /* |
5147 | * For simplicity, we won't allow this to be disabled. It also can't | 5126 | * For simplicity, we won't allow this to be disabled. It also can't |
5148 | * be changed if the cgroup has children already, or if tasks had | 5127 | * be changed if the cgroup has children already, or if tasks had |
@@ -5158,7 +5137,7 @@ static int memcg_update_kmem_limit(struct cgroup *cont, u64 val) | |||
5158 | mutex_lock(&memcg_create_mutex); | 5137 | mutex_lock(&memcg_create_mutex); |
5159 | mutex_lock(&set_limit_mutex); | 5138 | mutex_lock(&set_limit_mutex); |
5160 | if (!memcg->kmem_account_flags && val != RESOURCE_MAX) { | 5139 | if (!memcg->kmem_account_flags && val != RESOURCE_MAX) { |
5161 | if (cgroup_task_count(cont) || memcg_has_children(memcg)) { | 5140 | if (cgroup_task_count(css->cgroup) || memcg_has_children(memcg)) { |
5162 | ret = -EBUSY; | 5141 | ret = -EBUSY; |
5163 | goto out; | 5142 | goto out; |
5164 | } | 5143 | } |
@@ -5228,10 +5207,10 @@ out: | |||
5228 | * The user of this function is... | 5207 | * The user of this function is... |
5229 | * RES_LIMIT. | 5208 | * RES_LIMIT. |
5230 | */ | 5209 | */ |
5231 | static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, | 5210 | static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft, |
5232 | const char *buffer) | 5211 | const char *buffer) |
5233 | { | 5212 | { |
5234 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5213 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5235 | enum res_type type; | 5214 | enum res_type type; |
5236 | int name; | 5215 | int name; |
5237 | unsigned long long val; | 5216 | unsigned long long val; |
@@ -5255,7 +5234,7 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, | |||
5255 | else if (type == _MEMSWAP) | 5234 | else if (type == _MEMSWAP) |
5256 | ret = mem_cgroup_resize_memsw_limit(memcg, val); | 5235 | ret = mem_cgroup_resize_memsw_limit(memcg, val); |
5257 | else if (type == _KMEM) | 5236 | else if (type == _KMEM) |
5258 | ret = memcg_update_kmem_limit(cont, val); | 5237 | ret = memcg_update_kmem_limit(css, val); |
5259 | else | 5238 | else |
5260 | return -EINVAL; | 5239 | return -EINVAL; |
5261 | break; | 5240 | break; |
@@ -5283,18 +5262,15 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, | |||
5283 | static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg, | 5262 | static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg, |
5284 | unsigned long long *mem_limit, unsigned long long *memsw_limit) | 5263 | unsigned long long *mem_limit, unsigned long long *memsw_limit) |
5285 | { | 5264 | { |
5286 | struct cgroup *cgroup; | ||
5287 | unsigned long long min_limit, min_memsw_limit, tmp; | 5265 | unsigned long long min_limit, min_memsw_limit, tmp; |
5288 | 5266 | ||
5289 | min_limit = res_counter_read_u64(&memcg->res, RES_LIMIT); | 5267 | min_limit = res_counter_read_u64(&memcg->res, RES_LIMIT); |
5290 | min_memsw_limit = res_counter_read_u64(&memcg->memsw, RES_LIMIT); | 5268 | min_memsw_limit = res_counter_read_u64(&memcg->memsw, RES_LIMIT); |
5291 | cgroup = memcg->css.cgroup; | ||
5292 | if (!memcg->use_hierarchy) | 5269 | if (!memcg->use_hierarchy) |
5293 | goto out; | 5270 | goto out; |
5294 | 5271 | ||
5295 | while (cgroup->parent) { | 5272 | while (css_parent(&memcg->css)) { |
5296 | cgroup = cgroup->parent; | 5273 | memcg = mem_cgroup_from_css(css_parent(&memcg->css)); |
5297 | memcg = mem_cgroup_from_cont(cgroup); | ||
5298 | if (!memcg->use_hierarchy) | 5274 | if (!memcg->use_hierarchy) |
5299 | break; | 5275 | break; |
5300 | tmp = res_counter_read_u64(&memcg->res, RES_LIMIT); | 5276 | tmp = res_counter_read_u64(&memcg->res, RES_LIMIT); |
@@ -5307,9 +5283,9 @@ out: | |||
5307 | *memsw_limit = min_memsw_limit; | 5283 | *memsw_limit = min_memsw_limit; |
5308 | } | 5284 | } |
5309 | 5285 | ||
5310 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) | 5286 | static int mem_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event) |
5311 | { | 5287 | { |
5312 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5288 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5313 | int name; | 5289 | int name; |
5314 | enum res_type type; | 5290 | enum res_type type; |
5315 | 5291 | ||
@@ -5342,17 +5318,17 @@ static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) | |||
5342 | return 0; | 5318 | return 0; |
5343 | } | 5319 | } |
5344 | 5320 | ||
5345 | static u64 mem_cgroup_move_charge_read(struct cgroup *cgrp, | 5321 | static u64 mem_cgroup_move_charge_read(struct cgroup_subsys_state *css, |
5346 | struct cftype *cft) | 5322 | struct cftype *cft) |
5347 | { | 5323 | { |
5348 | return mem_cgroup_from_cont(cgrp)->move_charge_at_immigrate; | 5324 | return mem_cgroup_from_css(css)->move_charge_at_immigrate; |
5349 | } | 5325 | } |
5350 | 5326 | ||
5351 | #ifdef CONFIG_MMU | 5327 | #ifdef CONFIG_MMU |
5352 | static int mem_cgroup_move_charge_write(struct cgroup *cgrp, | 5328 | static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css, |
5353 | struct cftype *cft, u64 val) | 5329 | struct cftype *cft, u64 val) |
5354 | { | 5330 | { |
5355 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5331 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5356 | 5332 | ||
5357 | if (val >= (1 << NR_MOVE_TYPE)) | 5333 | if (val >= (1 << NR_MOVE_TYPE)) |
5358 | return -EINVAL; | 5334 | return -EINVAL; |
@@ -5367,7 +5343,7 @@ static int mem_cgroup_move_charge_write(struct cgroup *cgrp, | |||
5367 | return 0; | 5343 | return 0; |
5368 | } | 5344 | } |
5369 | #else | 5345 | #else |
5370 | static int mem_cgroup_move_charge_write(struct cgroup *cgrp, | 5346 | static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css, |
5371 | struct cftype *cft, u64 val) | 5347 | struct cftype *cft, u64 val) |
5372 | { | 5348 | { |
5373 | return -ENOSYS; | 5349 | return -ENOSYS; |
@@ -5375,13 +5351,13 @@ static int mem_cgroup_move_charge_write(struct cgroup *cgrp, | |||
5375 | #endif | 5351 | #endif |
5376 | 5352 | ||
5377 | #ifdef CONFIG_NUMA | 5353 | #ifdef CONFIG_NUMA |
5378 | static int memcg_numa_stat_show(struct cgroup *cont, struct cftype *cft, | 5354 | static int memcg_numa_stat_show(struct cgroup_subsys_state *css, |
5379 | struct seq_file *m) | 5355 | struct cftype *cft, struct seq_file *m) |
5380 | { | 5356 | { |
5381 | int nid; | 5357 | int nid; |
5382 | unsigned long total_nr, file_nr, anon_nr, unevictable_nr; | 5358 | unsigned long total_nr, file_nr, anon_nr, unevictable_nr; |
5383 | unsigned long node_nr; | 5359 | unsigned long node_nr; |
5384 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5360 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5385 | 5361 | ||
5386 | total_nr = mem_cgroup_nr_lru_pages(memcg, LRU_ALL); | 5362 | total_nr = mem_cgroup_nr_lru_pages(memcg, LRU_ALL); |
5387 | seq_printf(m, "total=%lu", total_nr); | 5363 | seq_printf(m, "total=%lu", total_nr); |
@@ -5426,10 +5402,10 @@ static inline void mem_cgroup_lru_names_not_uptodate(void) | |||
5426 | BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); | 5402 | BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); |
5427 | } | 5403 | } |
5428 | 5404 | ||
5429 | static int memcg_stat_show(struct cgroup *cont, struct cftype *cft, | 5405 | static int memcg_stat_show(struct cgroup_subsys_state *css, struct cftype *cft, |
5430 | struct seq_file *m) | 5406 | struct seq_file *m) |
5431 | { | 5407 | { |
5432 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 5408 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5433 | struct mem_cgroup *mi; | 5409 | struct mem_cgroup *mi; |
5434 | unsigned int i; | 5410 | unsigned int i; |
5435 | 5411 | ||
@@ -5513,27 +5489,23 @@ static int memcg_stat_show(struct cgroup *cont, struct cftype *cft, | |||
5513 | return 0; | 5489 | return 0; |
5514 | } | 5490 | } |
5515 | 5491 | ||
5516 | static u64 mem_cgroup_swappiness_read(struct cgroup *cgrp, struct cftype *cft) | 5492 | static u64 mem_cgroup_swappiness_read(struct cgroup_subsys_state *css, |
5493 | struct cftype *cft) | ||
5517 | { | 5494 | { |
5518 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5495 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5519 | 5496 | ||
5520 | return mem_cgroup_swappiness(memcg); | 5497 | return mem_cgroup_swappiness(memcg); |
5521 | } | 5498 | } |
5522 | 5499 | ||
5523 | static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, | 5500 | static int mem_cgroup_swappiness_write(struct cgroup_subsys_state *css, |
5524 | u64 val) | 5501 | struct cftype *cft, u64 val) |
5525 | { | 5502 | { |
5526 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5503 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5527 | struct mem_cgroup *parent; | 5504 | struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(&memcg->css)); |
5528 | |||
5529 | if (val > 100) | ||
5530 | return -EINVAL; | ||
5531 | 5505 | ||
5532 | if (cgrp->parent == NULL) | 5506 | if (val > 100 || !parent) |
5533 | return -EINVAL; | 5507 | return -EINVAL; |
5534 | 5508 | ||
5535 | parent = mem_cgroup_from_cont(cgrp->parent); | ||
5536 | |||
5537 | mutex_lock(&memcg_create_mutex); | 5509 | mutex_lock(&memcg_create_mutex); |
5538 | 5510 | ||
5539 | /* If under hierarchy, only empty-root can set this value */ | 5511 | /* If under hierarchy, only empty-root can set this value */ |
@@ -5636,10 +5608,10 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg) | |||
5636 | mem_cgroup_oom_notify_cb(iter); | 5608 | mem_cgroup_oom_notify_cb(iter); |
5637 | } | 5609 | } |
5638 | 5610 | ||
5639 | static int mem_cgroup_usage_register_event(struct cgroup *cgrp, | 5611 | static int mem_cgroup_usage_register_event(struct cgroup_subsys_state *css, |
5640 | struct cftype *cft, struct eventfd_ctx *eventfd, const char *args) | 5612 | struct cftype *cft, struct eventfd_ctx *eventfd, const char *args) |
5641 | { | 5613 | { |
5642 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5614 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5643 | struct mem_cgroup_thresholds *thresholds; | 5615 | struct mem_cgroup_thresholds *thresholds; |
5644 | struct mem_cgroup_threshold_ary *new; | 5616 | struct mem_cgroup_threshold_ary *new; |
5645 | enum res_type type = MEMFILE_TYPE(cft->private); | 5617 | enum res_type type = MEMFILE_TYPE(cft->private); |
@@ -5719,10 +5691,10 @@ unlock: | |||
5719 | return ret; | 5691 | return ret; |
5720 | } | 5692 | } |
5721 | 5693 | ||
5722 | static void mem_cgroup_usage_unregister_event(struct cgroup *cgrp, | 5694 | static void mem_cgroup_usage_unregister_event(struct cgroup_subsys_state *css, |
5723 | struct cftype *cft, struct eventfd_ctx *eventfd) | 5695 | struct cftype *cft, struct eventfd_ctx *eventfd) |
5724 | { | 5696 | { |
5725 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5697 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5726 | struct mem_cgroup_thresholds *thresholds; | 5698 | struct mem_cgroup_thresholds *thresholds; |
5727 | struct mem_cgroup_threshold_ary *new; | 5699 | struct mem_cgroup_threshold_ary *new; |
5728 | enum res_type type = MEMFILE_TYPE(cft->private); | 5700 | enum res_type type = MEMFILE_TYPE(cft->private); |
@@ -5798,10 +5770,10 @@ unlock: | |||
5798 | mutex_unlock(&memcg->thresholds_lock); | 5770 | mutex_unlock(&memcg->thresholds_lock); |
5799 | } | 5771 | } |
5800 | 5772 | ||
5801 | static int mem_cgroup_oom_register_event(struct cgroup *cgrp, | 5773 | static int mem_cgroup_oom_register_event(struct cgroup_subsys_state *css, |
5802 | struct cftype *cft, struct eventfd_ctx *eventfd, const char *args) | 5774 | struct cftype *cft, struct eventfd_ctx *eventfd, const char *args) |
5803 | { | 5775 | { |
5804 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5776 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5805 | struct mem_cgroup_eventfd_list *event; | 5777 | struct mem_cgroup_eventfd_list *event; |
5806 | enum res_type type = MEMFILE_TYPE(cft->private); | 5778 | enum res_type type = MEMFILE_TYPE(cft->private); |
5807 | 5779 | ||
@@ -5823,10 +5795,10 @@ static int mem_cgroup_oom_register_event(struct cgroup *cgrp, | |||
5823 | return 0; | 5795 | return 0; |
5824 | } | 5796 | } |
5825 | 5797 | ||
5826 | static void mem_cgroup_oom_unregister_event(struct cgroup *cgrp, | 5798 | static void mem_cgroup_oom_unregister_event(struct cgroup_subsys_state *css, |
5827 | struct cftype *cft, struct eventfd_ctx *eventfd) | 5799 | struct cftype *cft, struct eventfd_ctx *eventfd) |
5828 | { | 5800 | { |
5829 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5801 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5830 | struct mem_cgroup_eventfd_list *ev, *tmp; | 5802 | struct mem_cgroup_eventfd_list *ev, *tmp; |
5831 | enum res_type type = MEMFILE_TYPE(cft->private); | 5803 | enum res_type type = MEMFILE_TYPE(cft->private); |
5832 | 5804 | ||
@@ -5844,10 +5816,10 @@ static void mem_cgroup_oom_unregister_event(struct cgroup *cgrp, | |||
5844 | spin_unlock(&memcg_oom_lock); | 5816 | spin_unlock(&memcg_oom_lock); |
5845 | } | 5817 | } |
5846 | 5818 | ||
5847 | static int mem_cgroup_oom_control_read(struct cgroup *cgrp, | 5819 | static int mem_cgroup_oom_control_read(struct cgroup_subsys_state *css, |
5848 | struct cftype *cft, struct cgroup_map_cb *cb) | 5820 | struct cftype *cft, struct cgroup_map_cb *cb) |
5849 | { | 5821 | { |
5850 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5822 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5851 | 5823 | ||
5852 | cb->fill(cb, "oom_kill_disable", memcg->oom_kill_disable); | 5824 | cb->fill(cb, "oom_kill_disable", memcg->oom_kill_disable); |
5853 | 5825 | ||
@@ -5858,18 +5830,16 @@ static int mem_cgroup_oom_control_read(struct cgroup *cgrp, | |||
5858 | return 0; | 5830 | return 0; |
5859 | } | 5831 | } |
5860 | 5832 | ||
5861 | static int mem_cgroup_oom_control_write(struct cgroup *cgrp, | 5833 | static int mem_cgroup_oom_control_write(struct cgroup_subsys_state *css, |
5862 | struct cftype *cft, u64 val) | 5834 | struct cftype *cft, u64 val) |
5863 | { | 5835 | { |
5864 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); | 5836 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5865 | struct mem_cgroup *parent; | 5837 | struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(&memcg->css)); |
5866 | 5838 | ||
5867 | /* cannot set to root cgroup and only 0 and 1 are allowed */ | 5839 | /* cannot set to root cgroup and only 0 and 1 are allowed */ |
5868 | if (!cgrp->parent || !((val == 0) || (val == 1))) | 5840 | if (!parent || !((val == 0) || (val == 1))) |
5869 | return -EINVAL; | 5841 | return -EINVAL; |
5870 | 5842 | ||
5871 | parent = mem_cgroup_from_cont(cgrp->parent); | ||
5872 | |||
5873 | mutex_lock(&memcg_create_mutex); | 5843 | mutex_lock(&memcg_create_mutex); |
5874 | /* oom-kill-disable is a flag for subhierarchy. */ | 5844 | /* oom-kill-disable is a flag for subhierarchy. */ |
5875 | if ((parent->use_hierarchy) || memcg_has_children(memcg)) { | 5845 | if ((parent->use_hierarchy) || memcg_has_children(memcg)) { |
@@ -6228,7 +6198,7 @@ static void __init mem_cgroup_soft_limit_tree_init(void) | |||
6228 | } | 6198 | } |
6229 | 6199 | ||
6230 | static struct cgroup_subsys_state * __ref | 6200 | static struct cgroup_subsys_state * __ref |
6231 | mem_cgroup_css_alloc(struct cgroup *cont) | 6201 | mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) |
6232 | { | 6202 | { |
6233 | struct mem_cgroup *memcg; | 6203 | struct mem_cgroup *memcg; |
6234 | long error = -ENOMEM; | 6204 | long error = -ENOMEM; |
@@ -6243,7 +6213,7 @@ mem_cgroup_css_alloc(struct cgroup *cont) | |||
6243 | goto free_out; | 6213 | goto free_out; |
6244 | 6214 | ||
6245 | /* root ? */ | 6215 | /* root ? */ |
6246 | if (cont->parent == NULL) { | 6216 | if (parent_css == NULL) { |
6247 | root_mem_cgroup = memcg; | 6217 | root_mem_cgroup = memcg; |
6248 | res_counter_init(&memcg->res, NULL); | 6218 | res_counter_init(&memcg->res, NULL); |
6249 | res_counter_init(&memcg->memsw, NULL); | 6219 | res_counter_init(&memcg->memsw, NULL); |
@@ -6265,17 +6235,16 @@ free_out: | |||
6265 | } | 6235 | } |
6266 | 6236 | ||
6267 | static int | 6237 | static int |
6268 | mem_cgroup_css_online(struct cgroup *cont) | 6238 | mem_cgroup_css_online(struct cgroup_subsys_state *css) |
6269 | { | 6239 | { |
6270 | struct mem_cgroup *memcg, *parent; | 6240 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
6241 | struct mem_cgroup *parent = mem_cgroup_from_css(css_parent(css)); | ||
6271 | int error = 0; | 6242 | int error = 0; |
6272 | 6243 | ||
6273 | if (!cont->parent) | 6244 | if (!parent) |
6274 | return 0; | 6245 | return 0; |
6275 | 6246 | ||
6276 | mutex_lock(&memcg_create_mutex); | 6247 | mutex_lock(&memcg_create_mutex); |
6277 | memcg = mem_cgroup_from_cont(cont); | ||
6278 | parent = mem_cgroup_from_cont(cont->parent); | ||
6279 | 6248 | ||
6280 | memcg->use_hierarchy = parent->use_hierarchy; | 6249 | memcg->use_hierarchy = parent->use_hierarchy; |
6281 | memcg->oom_kill_disable = parent->oom_kill_disable; | 6250 | memcg->oom_kill_disable = parent->oom_kill_disable; |
@@ -6326,9 +6295,9 @@ static void mem_cgroup_invalidate_reclaim_iterators(struct mem_cgroup *memcg) | |||
6326 | mem_cgroup_iter_invalidate(root_mem_cgroup); | 6295 | mem_cgroup_iter_invalidate(root_mem_cgroup); |
6327 | } | 6296 | } |
6328 | 6297 | ||
6329 | static void mem_cgroup_css_offline(struct cgroup *cont) | 6298 | static void mem_cgroup_css_offline(struct cgroup_subsys_state *css) |
6330 | { | 6299 | { |
6331 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 6300 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
6332 | 6301 | ||
6333 | kmem_cgroup_css_offline(memcg); | 6302 | kmem_cgroup_css_offline(memcg); |
6334 | 6303 | ||
@@ -6338,9 +6307,9 @@ static void mem_cgroup_css_offline(struct cgroup *cont) | |||
6338 | vmpressure_cleanup(&memcg->vmpressure); | 6307 | vmpressure_cleanup(&memcg->vmpressure); |
6339 | } | 6308 | } |
6340 | 6309 | ||
6341 | static void mem_cgroup_css_free(struct cgroup *cont) | 6310 | static void mem_cgroup_css_free(struct cgroup_subsys_state *css) |
6342 | { | 6311 | { |
6343 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 6312 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
6344 | 6313 | ||
6345 | memcg_destroy_kmem(memcg); | 6314 | memcg_destroy_kmem(memcg); |
6346 | __mem_cgroup_free(memcg); | 6315 | __mem_cgroup_free(memcg); |
@@ -6710,12 +6679,12 @@ static void mem_cgroup_clear_mc(void) | |||
6710 | mem_cgroup_end_move(from); | 6679 | mem_cgroup_end_move(from); |
6711 | } | 6680 | } |
6712 | 6681 | ||
6713 | static int mem_cgroup_can_attach(struct cgroup *cgroup, | 6682 | static int mem_cgroup_can_attach(struct cgroup_subsys_state *css, |
6714 | struct cgroup_taskset *tset) | 6683 | struct cgroup_taskset *tset) |
6715 | { | 6684 | { |
6716 | struct task_struct *p = cgroup_taskset_first(tset); | 6685 | struct task_struct *p = cgroup_taskset_first(tset); |
6717 | int ret = 0; | 6686 | int ret = 0; |
6718 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cgroup); | 6687 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
6719 | unsigned long move_charge_at_immigrate; | 6688 | unsigned long move_charge_at_immigrate; |
6720 | 6689 | ||
6721 | /* | 6690 | /* |
@@ -6757,7 +6726,7 @@ static int mem_cgroup_can_attach(struct cgroup *cgroup, | |||
6757 | return ret; | 6726 | return ret; |
6758 | } | 6727 | } |
6759 | 6728 | ||
6760 | static void mem_cgroup_cancel_attach(struct cgroup *cgroup, | 6729 | static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css, |
6761 | struct cgroup_taskset *tset) | 6730 | struct cgroup_taskset *tset) |
6762 | { | 6731 | { |
6763 | mem_cgroup_clear_mc(); | 6732 | mem_cgroup_clear_mc(); |
@@ -6905,7 +6874,7 @@ retry: | |||
6905 | up_read(&mm->mmap_sem); | 6874 | up_read(&mm->mmap_sem); |
6906 | } | 6875 | } |
6907 | 6876 | ||
6908 | static void mem_cgroup_move_task(struct cgroup *cont, | 6877 | static void mem_cgroup_move_task(struct cgroup_subsys_state *css, |
6909 | struct cgroup_taskset *tset) | 6878 | struct cgroup_taskset *tset) |
6910 | { | 6879 | { |
6911 | struct task_struct *p = cgroup_taskset_first(tset); | 6880 | struct task_struct *p = cgroup_taskset_first(tset); |
@@ -6920,16 +6889,16 @@ static void mem_cgroup_move_task(struct cgroup *cont, | |||
6920 | mem_cgroup_clear_mc(); | 6889 | mem_cgroup_clear_mc(); |
6921 | } | 6890 | } |
6922 | #else /* !CONFIG_MMU */ | 6891 | #else /* !CONFIG_MMU */ |
6923 | static int mem_cgroup_can_attach(struct cgroup *cgroup, | 6892 | static int mem_cgroup_can_attach(struct cgroup_subsys_state *css, |
6924 | struct cgroup_taskset *tset) | 6893 | struct cgroup_taskset *tset) |
6925 | { | 6894 | { |
6926 | return 0; | 6895 | return 0; |
6927 | } | 6896 | } |
6928 | static void mem_cgroup_cancel_attach(struct cgroup *cgroup, | 6897 | static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css, |
6929 | struct cgroup_taskset *tset) | 6898 | struct cgroup_taskset *tset) |
6930 | { | 6899 | { |
6931 | } | 6900 | } |
6932 | static void mem_cgroup_move_task(struct cgroup *cont, | 6901 | static void mem_cgroup_move_task(struct cgroup_subsys_state *css, |
6933 | struct cgroup_taskset *tset) | 6902 | struct cgroup_taskset *tset) |
6934 | { | 6903 | { |
6935 | } | 6904 | } |
@@ -6939,15 +6908,15 @@ static void mem_cgroup_move_task(struct cgroup *cont, | |||
6939 | * Cgroup retains root cgroups across [un]mount cycles making it necessary | 6908 | * Cgroup retains root cgroups across [un]mount cycles making it necessary |
6940 | * to verify sane_behavior flag on each mount attempt. | 6909 | * to verify sane_behavior flag on each mount attempt. |
6941 | */ | 6910 | */ |
6942 | static void mem_cgroup_bind(struct cgroup *root) | 6911 | static void mem_cgroup_bind(struct cgroup_subsys_state *root_css) |
6943 | { | 6912 | { |
6944 | /* | 6913 | /* |
6945 | * use_hierarchy is forced with sane_behavior. cgroup core | 6914 | * use_hierarchy is forced with sane_behavior. cgroup core |
6946 | * guarantees that @root doesn't have any children, so turning it | 6915 | * guarantees that @root doesn't have any children, so turning it |
6947 | * on for the root memcg is enough. | 6916 | * on for the root memcg is enough. |
6948 | */ | 6917 | */ |
6949 | if (cgroup_sane_behavior(root)) | 6918 | if (cgroup_sane_behavior(root_css->cgroup)) |
6950 | mem_cgroup_from_cont(root)->use_hierarchy = true; | 6919 | mem_cgroup_from_css(root_css)->use_hierarchy = true; |
6951 | } | 6920 | } |
6952 | 6921 | ||
6953 | struct cgroup_subsys mem_cgroup_subsys = { | 6922 | struct cgroup_subsys mem_cgroup_subsys = { |
diff --git a/mm/vmpressure.c b/mm/vmpressure.c index 0c1e37d829fa..e0f62837c3f4 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c | |||
@@ -74,15 +74,10 @@ static struct vmpressure *work_to_vmpressure(struct work_struct *work) | |||
74 | return container_of(work, struct vmpressure, work); | 74 | return container_of(work, struct vmpressure, work); |
75 | } | 75 | } |
76 | 76 | ||
77 | static struct vmpressure *cg_to_vmpressure(struct cgroup *cg) | ||
78 | { | ||
79 | return css_to_vmpressure(cgroup_subsys_state(cg, mem_cgroup_subsys_id)); | ||
80 | } | ||
81 | |||
82 | static struct vmpressure *vmpressure_parent(struct vmpressure *vmpr) | 77 | static struct vmpressure *vmpressure_parent(struct vmpressure *vmpr) |
83 | { | 78 | { |
84 | struct cgroup *cg = vmpressure_to_css(vmpr)->cgroup; | 79 | struct cgroup_subsys_state *css = vmpressure_to_css(vmpr); |
85 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cg); | 80 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
86 | 81 | ||
87 | memcg = parent_mem_cgroup(memcg); | 82 | memcg = parent_mem_cgroup(memcg); |
88 | if (!memcg) | 83 | if (!memcg) |
@@ -283,7 +278,7 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) | |||
283 | 278 | ||
284 | /** | 279 | /** |
285 | * vmpressure_register_event() - Bind vmpressure notifications to an eventfd | 280 | * vmpressure_register_event() - Bind vmpressure notifications to an eventfd |
286 | * @cg: cgroup that is interested in vmpressure notifications | 281 | * @css: css that is interested in vmpressure notifications |
287 | * @cft: cgroup control files handle | 282 | * @cft: cgroup control files handle |
288 | * @eventfd: eventfd context to link notifications with | 283 | * @eventfd: eventfd context to link notifications with |
289 | * @args: event arguments (used to set up a pressure level threshold) | 284 | * @args: event arguments (used to set up a pressure level threshold) |
@@ -298,10 +293,11 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) | |||
298 | * cftype).register_event, and then cgroup core will handle everything by | 293 | * cftype).register_event, and then cgroup core will handle everything by |
299 | * itself. | 294 | * itself. |
300 | */ | 295 | */ |
301 | int vmpressure_register_event(struct cgroup *cg, struct cftype *cft, | 296 | int vmpressure_register_event(struct cgroup_subsys_state *css, |
302 | struct eventfd_ctx *eventfd, const char *args) | 297 | struct cftype *cft, struct eventfd_ctx *eventfd, |
298 | const char *args) | ||
303 | { | 299 | { |
304 | struct vmpressure *vmpr = cg_to_vmpressure(cg); | 300 | struct vmpressure *vmpr = css_to_vmpressure(css); |
305 | struct vmpressure_event *ev; | 301 | struct vmpressure_event *ev; |
306 | int level; | 302 | int level; |
307 | 303 | ||
@@ -329,7 +325,7 @@ int vmpressure_register_event(struct cgroup *cg, struct cftype *cft, | |||
329 | 325 | ||
330 | /** | 326 | /** |
331 | * vmpressure_unregister_event() - Unbind eventfd from vmpressure | 327 | * vmpressure_unregister_event() - Unbind eventfd from vmpressure |
332 | * @cg: cgroup handle | 328 | * @css: css handle |
333 | * @cft: cgroup control files handle | 329 | * @cft: cgroup control files handle |
334 | * @eventfd: eventfd context that was used to link vmpressure with the @cg | 330 | * @eventfd: eventfd context that was used to link vmpressure with the @cg |
335 | * | 331 | * |
@@ -341,10 +337,11 @@ int vmpressure_register_event(struct cgroup *cg, struct cftype *cft, | |||
341 | * cftype).unregister_event, and then cgroup core will handle everything | 337 | * cftype).unregister_event, and then cgroup core will handle everything |
342 | * by itself. | 338 | * by itself. |
343 | */ | 339 | */ |
344 | void vmpressure_unregister_event(struct cgroup *cg, struct cftype *cft, | 340 | void vmpressure_unregister_event(struct cgroup_subsys_state *css, |
341 | struct cftype *cft, | ||
345 | struct eventfd_ctx *eventfd) | 342 | struct eventfd_ctx *eventfd) |
346 | { | 343 | { |
347 | struct vmpressure *vmpr = cg_to_vmpressure(cg); | 344 | struct vmpressure *vmpr = css_to_vmpressure(css); |
348 | struct vmpressure_event *ev; | 345 | struct vmpressure_event *ev; |
349 | 346 | ||
350 | mutex_lock(&vmpr->events_lock); | 347 | mutex_lock(&vmpr->events_lock); |