aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill@shutemov.name>2010-03-10 18:22:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-12 18:52:37 -0500
commita0a4db548edcce067c1201ef25cf2bc29f32dca4 (patch)
tree6f8139a582179666cd248d978332ed0e32ad9f0f
parent4ab78683c17d739c2a2077141dcf81a02b7fb57e (diff)
cgroups: remove events before destroying subsystem state objects
Events should be removed after rmdir of cgroup directory, but before destroying subsystem state objects. Let's take reference to cgroup directory dentry to do that. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hioryu@jp.fujitsu.com> Cc: Paul Menage <menage@google.com> Acked-by: Li Zefan <lizf@cn.fujitsu.com> Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Dan Malek <dan@embeddedalley.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/cgroup.h3
-rw-r--r--kernel/cgroup.c8
-rw-r--r--mm/memcontrol.c9
3 files changed, 8 insertions, 12 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b4f2201321cd..b8ad1ea99586 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -396,9 +396,6 @@ struct cftype {
396 * closes the eventfd or on cgroup removing. 396 * closes the eventfd or on cgroup removing.
397 * This callback must be implemented, if you want provide 397 * This callback must be implemented, if you want provide
398 * notification functionality. 398 * notification functionality.
399 *
400 * Be careful. It can be called after destroy(), so you have
401 * to keep all nesessary data, until all events are removed.
402 */ 399 */
403 int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft, 400 int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft,
404 struct eventfd_ctx *eventfd); 401 struct eventfd_ctx *eventfd);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 87441fc75663..ef909a329750 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2994,6 +2994,7 @@ static void cgroup_event_remove(struct work_struct *work)
2994 2994
2995 eventfd_ctx_put(event->eventfd); 2995 eventfd_ctx_put(event->eventfd);
2996 kfree(event); 2996 kfree(event);
2997 dput(cgrp->dentry);
2997} 2998}
2998 2999
2999/* 3000/*
@@ -3114,6 +3115,13 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
3114 goto fail; 3115 goto fail;
3115 } 3116 }
3116 3117
3118 /*
3119 * Events should be removed after rmdir of cgroup directory, but before
3120 * destroying subsystem state objects. Let's take reference to cgroup
3121 * directory dentry to do that.
3122 */
3123 dget(cgrp->dentry);
3124
3117 spin_lock(&cgrp->event_list_lock); 3125 spin_lock(&cgrp->event_list_lock);
3118 list_add(&event->list, &cgrp->event_list); 3126 list_add(&event->list, &cgrp->event_list);
3119 spin_unlock(&cgrp->event_list_lock); 3127 spin_unlock(&cgrp->event_list_lock);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f9ae4b4c36eb..f7b910fc14fb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3361,12 +3361,6 @@ static int mem_cgroup_register_event(struct cgroup *cgrp, struct cftype *cft,
3361 } 3361 }
3362 } 3362 }
3363 3363
3364 /*
3365 * We need to increment refcnt to be sure that all thresholds
3366 * will be unregistered before calling __mem_cgroup_free()
3367 */
3368 mem_cgroup_get(memcg);
3369
3370 if (type == _MEM) 3364 if (type == _MEM)
3371 rcu_assign_pointer(memcg->thresholds, thresholds_new); 3365 rcu_assign_pointer(memcg->thresholds, thresholds_new);
3372 else 3366 else
@@ -3460,9 +3454,6 @@ assign:
3460 /* To be sure that nobody uses thresholds before freeing it */ 3454 /* To be sure that nobody uses thresholds before freeing it */
3461 synchronize_rcu(); 3455 synchronize_rcu();
3462 3456
3463 for (i = 0; i < thresholds->size - size; i++)
3464 mem_cgroup_put(memcg);
3465
3466 kfree(thresholds); 3457 kfree(thresholds);
3467unlock: 3458unlock:
3468 mutex_unlock(&memcg->thresholds_lock); 3459 mutex_unlock(&memcg->thresholds_lock);