diff options
author | Li Zefan <lizefan@huawei.com> | 2013-07-08 19:00:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 13:33:24 -0400 |
commit | 465939a1fa283cf2a5194362c5accf4429c99c42 (patch) | |
tree | 5ef779db1f628b738001e44cad6955991cb06a0b /mm/memcontrol.c | |
parent | e0743e6bc5b7587dd0bfa902d67d3f81ef3f6618 (diff) |
memcg: don't need to free memcg via RCU or workqueue
Now memcg has the same life cycle with its corresponding cgroup, and a
cgroup is freed via RCU and then mem_cgroup_css_free() will be called in
a work function, so we can simply call __mem_cgroup_free() in
mem_cgroup_css_free().
This actually reverts commit 59927fb984d ("memcg: free mem_cgroup by RCU
to fix oops").
Signed-off-by: Li Zefan <lizefan@huawei.com>
Cc: Hugh Dickins <hughd@google.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Glauber Costa <glommer@openvz.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 51 |
1 files changed, 5 insertions, 46 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fa521a2f4bf6..d12ca6f3c293 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -263,28 +263,10 @@ struct mem_cgroup { | |||
263 | /* vmpressure notifications */ | 263 | /* vmpressure notifications */ |
264 | struct vmpressure vmpressure; | 264 | struct vmpressure vmpressure; |
265 | 265 | ||
266 | union { | 266 | /* |
267 | /* | 267 | * the counter to account for mem+swap usage. |
268 | * the counter to account for mem+swap usage. | 268 | */ |
269 | */ | 269 | struct res_counter memsw; |
270 | struct res_counter memsw; | ||
271 | |||
272 | /* | ||
273 | * rcu_freeing is used only when freeing struct mem_cgroup, | ||
274 | * so put it into a union to avoid wasting more memory. | ||
275 | * It must be disjoint from the css field. It could be | ||
276 | * in a union with the res field, but res plays a much | ||
277 | * larger part in mem_cgroup life than memsw, and might | ||
278 | * be of interest, even at time of free, when debugging. | ||
279 | * So share rcu_head with the less interesting memsw. | ||
280 | */ | ||
281 | struct rcu_head rcu_freeing; | ||
282 | /* | ||
283 | * We also need some space for a worker in deferred freeing. | ||
284 | * By the time we call it, rcu_freeing is no longer in use. | ||
285 | */ | ||
286 | struct work_struct work_freeing; | ||
287 | }; | ||
288 | 270 | ||
289 | /* | 271 | /* |
290 | * the counter to account for kernel memory usage. | 272 | * the counter to account for kernel memory usage. |
@@ -6211,29 +6193,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) | |||
6211 | vfree(memcg); | 6193 | vfree(memcg); |
6212 | } | 6194 | } |
6213 | 6195 | ||
6214 | |||
6215 | /* | ||
6216 | * Helpers for freeing a kmalloc()ed/vzalloc()ed mem_cgroup by RCU, | ||
6217 | * but in process context. The work_freeing structure is overlaid | ||
6218 | * on the rcu_freeing structure, which itself is overlaid on memsw. | ||
6219 | */ | ||
6220 | static void free_work(struct work_struct *work) | ||
6221 | { | ||
6222 | struct mem_cgroup *memcg; | ||
6223 | |||
6224 | memcg = container_of(work, struct mem_cgroup, work_freeing); | ||
6225 | __mem_cgroup_free(memcg); | ||
6226 | } | ||
6227 | |||
6228 | static void free_rcu(struct rcu_head *rcu_head) | ||
6229 | { | ||
6230 | struct mem_cgroup *memcg; | ||
6231 | |||
6232 | memcg = container_of(rcu_head, struct mem_cgroup, rcu_freeing); | ||
6233 | INIT_WORK(&memcg->work_freeing, free_work); | ||
6234 | schedule_work(&memcg->work_freeing); | ||
6235 | } | ||
6236 | |||
6237 | /* | 6196 | /* |
6238 | * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. | 6197 | * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. |
6239 | */ | 6198 | */ |
@@ -6383,7 +6342,7 @@ static void mem_cgroup_css_free(struct cgroup *cont) | |||
6383 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 6342 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); |
6384 | 6343 | ||
6385 | memcg_destroy_kmem(memcg); | 6344 | memcg_destroy_kmem(memcg); |
6386 | call_rcu(&memcg->rcu_freeing, free_rcu); | 6345 | __mem_cgroup_free(memcg); |
6387 | } | 6346 | } |
6388 | 6347 | ||
6389 | #ifdef CONFIG_MMU | 6348 | #ifdef CONFIG_MMU |