aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--kernel/cgroup.c38
2 files changed, 28 insertions, 12 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 81bfd0268e93..e345d8b90046 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -233,7 +233,7 @@ struct cgroup {
233 233
234 /* For RCU-protected deletion */ 234 /* For RCU-protected deletion */
235 struct rcu_head rcu_head; 235 struct rcu_head rcu_head;
236 struct work_struct free_work; 236 struct work_struct destroy_work;
237 237
238 /* List of events which userspace want to receive */ 238 /* List of events which userspace want to receive */
239 struct list_head event_list; 239 struct list_head event_list;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 5a1ddecc3cfa..df6814706cca 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -208,6 +208,7 @@ static struct cgroup_name root_cgroup_name = { .name = "/" };
208 */ 208 */
209static int need_forkexit_callback __read_mostly; 209static int need_forkexit_callback __read_mostly;
210 210
211static void cgroup_offline_fn(struct work_struct *work);
211static int cgroup_destroy_locked(struct cgroup *cgrp); 212static int cgroup_destroy_locked(struct cgroup *cgrp);
212static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, 213static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
213 struct cftype cfts[], bool is_add); 214 struct cftype cfts[], bool is_add);
@@ -830,7 +831,7 @@ static struct cgroup_name *cgroup_alloc_name(struct dentry *dentry)
830 831
831static void cgroup_free_fn(struct work_struct *work) 832static void cgroup_free_fn(struct work_struct *work)
832{ 833{
833 struct cgroup *cgrp = container_of(work, struct cgroup, free_work); 834 struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
834 struct cgroup_subsys *ss; 835 struct cgroup_subsys *ss;
835 836
836 mutex_lock(&cgroup_mutex); 837 mutex_lock(&cgroup_mutex);
@@ -875,7 +876,8 @@ static void cgroup_free_rcu(struct rcu_head *head)
875{ 876{
876 struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head); 877 struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head);
877 878
878 schedule_work(&cgrp->free_work); 879 INIT_WORK(&cgrp->destroy_work, cgroup_free_fn);
880 schedule_work(&cgrp->destroy_work);
879} 881}
880 882
881static void cgroup_diput(struct dentry *dentry, struct inode *inode) 883static void cgroup_diput(struct dentry *dentry, struct inode *inode)
@@ -1407,7 +1409,6 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
1407 INIT_LIST_HEAD(&cgrp->allcg_node); 1409 INIT_LIST_HEAD(&cgrp->allcg_node);
1408 INIT_LIST_HEAD(&cgrp->release_list); 1410 INIT_LIST_HEAD(&cgrp->release_list);
1409 INIT_LIST_HEAD(&cgrp->pidlists); 1411 INIT_LIST_HEAD(&cgrp->pidlists);
1410 INIT_WORK(&cgrp->free_work, cgroup_free_fn);
1411 mutex_init(&cgrp->pidlist_mutex); 1412 mutex_init(&cgrp->pidlist_mutex);
1412 INIT_LIST_HEAD(&cgrp->event_list); 1413 INIT_LIST_HEAD(&cgrp->event_list);
1413 spin_lock_init(&cgrp->event_list_lock); 1414 spin_lock_init(&cgrp->event_list_lock);
@@ -2991,12 +2992,13 @@ struct cgroup *cgroup_next_sibling(struct cgroup *pos)
2991 /* 2992 /*
2992 * @pos could already have been removed. Once a cgroup is removed, 2993 * @pos could already have been removed. Once a cgroup is removed,
2993 * its ->sibling.next is no longer updated when its next sibling 2994 * its ->sibling.next is no longer updated when its next sibling
2994 * changes. As CGRP_DEAD is set on removal which is fully 2995 * changes. As CGRP_DEAD assertion is serialized and happens
2995 * serialized, if we see it unasserted, it's guaranteed that the 2996 * before the cgroup is taken off the ->sibling list, if we see it
2996 * next sibling hasn't finished its grace period even if it's 2997 * unasserted, it's guaranteed that the next sibling hasn't
2997 * already removed, and thus safe to dereference from this RCU 2998 * finished its grace period even if it's already removed, and thus
2998 * critical section. If ->sibling.next is inaccessible, 2999 * safe to dereference from this RCU critical section. If
2999 * cgroup_is_dead() is guaranteed to be visible as %true here. 3000 * ->sibling.next is inaccessible, cgroup_is_dead() is guaranteed
3001 * to be visible as %true here.
3000 */ 3002 */
3001 if (likely(!cgroup_is_dead(pos))) { 3003 if (likely(!cgroup_is_dead(pos))) {
3002 next = list_entry_rcu(pos->sibling.next, struct cgroup, sibling); 3004 next = list_entry_rcu(pos->sibling.next, struct cgroup, sibling);
@@ -4359,7 +4361,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4359 __releases(&cgroup_mutex) __acquires(&cgroup_mutex) 4361 __releases(&cgroup_mutex) __acquires(&cgroup_mutex)
4360{ 4362{
4361 struct dentry *d = cgrp->dentry; 4363 struct dentry *d = cgrp->dentry;
4362 struct cgroup *parent = cgrp->parent;
4363 struct cgroup_event *event, *tmp; 4364 struct cgroup_event *event, *tmp;
4364 struct cgroup_subsys *ss; 4365 struct cgroup_subsys *ss;
4365 bool empty; 4366 bool empty;
@@ -4423,6 +4424,21 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4423 } 4424 }
4424 spin_unlock(&cgrp->event_list_lock); 4425 spin_unlock(&cgrp->event_list_lock);
4425 4426
4427 INIT_WORK(&cgrp->destroy_work, cgroup_offline_fn);
4428 schedule_work(&cgrp->destroy_work);
4429
4430 return 0;
4431};
4432
4433static void cgroup_offline_fn(struct work_struct *work)
4434{
4435 struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
4436 struct cgroup *parent = cgrp->parent;
4437 struct dentry *d = cgrp->dentry;
4438 struct cgroup_subsys *ss;
4439
4440 mutex_lock(&cgroup_mutex);
4441
4426 /* tell subsystems to initate destruction */ 4442 /* tell subsystems to initate destruction */
4427 for_each_subsys(cgrp->root, ss) 4443 for_each_subsys(cgrp->root, ss)
4428 offline_css(ss, cgrp); 4444 offline_css(ss, cgrp);
@@ -4446,7 +4462,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4446 set_bit(CGRP_RELEASABLE, &parent->flags); 4462 set_bit(CGRP_RELEASABLE, &parent->flags);
4447 check_for_release(parent); 4463 check_for_release(parent);
4448 4464
4449 return 0; 4465 mutex_unlock(&cgroup_mutex);
4450} 4466}
4451 4467
4452static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) 4468static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)