|
@@ -965,33 +965,6 @@ static void cgroup_d_remove_dir(struct dentry *dentry)
|
|
|
remove_dir(dentry);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * A queue for waiters to do rmdir() cgroup. A tasks will sleep when
|
|
|
- * cgroup->count == 0 && list_empty(&cgroup->children) && subsys has some
|
|
|
- * reference to css->refcnt. In general, this refcnt is expected to goes down
|
|
|
- * to zero, soon.
|
|
|
- *
|
|
|
- * CGRP_WAIT_ON_RMDIR flag is set under cgroup's inode->i_mutex;
|
|
|
- */
|
|
|
-static DECLARE_WAIT_QUEUE_HEAD(cgroup_rmdir_waitq);
|
|
|
-
|
|
|
-static void cgroup_wakeup_rmdir_waiter(struct cgroup *cgrp)
|
|
|
-{
|
|
|
- if (unlikely(test_and_clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags)))
|
|
|
- wake_up_all(&cgroup_rmdir_waitq);
|
|
|
-}
|
|
|
-
|
|
|
-void cgroup_exclude_rmdir(struct cgroup_subsys_state *css)
|
|
|
-{
|
|
|
- css_get(css);
|
|
|
-}
|
|
|
-
|
|
|
-void cgroup_release_and_wakeup_rmdir(struct cgroup_subsys_state *css)
|
|
|
-{
|
|
|
- cgroup_wakeup_rmdir_waiter(css->cgroup);
|
|
|
- css_put(css);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Call with cgroup_mutex held. Drops reference counts on modules, including
|
|
|
* any duplicate ones that parse_cgroupfs_options took. If this function
|
|
@@ -1963,12 +1936,6 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
|
|
|
}
|
|
|
|
|
|
synchronize_rcu();
|
|
|
-
|
|
|
- /*
|
|
|
- * wake up rmdir() waiter. the rmdir should fail since the cgroup
|
|
|
- * is no longer empty.
|
|
|
- */
|
|
|
- cgroup_wakeup_rmdir_waiter(cgrp);
|
|
|
out:
|
|
|
if (retval) {
|
|
|
for_each_subsys(root, ss) {
|
|
@@ -2138,7 +2105,6 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
|
|
|
* step 5: success! and cleanup
|
|
|
*/
|
|
|
synchronize_rcu();
|
|
|
- cgroup_wakeup_rmdir_waiter(cgrp);
|
|
|
retval = 0;
|
|
|
out_put_css_set_refs:
|
|
|
if (retval) {
|
|
@@ -4058,26 +4024,13 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
|
|
|
struct cgroup_event *event, *tmp;
|
|
|
struct cgroup_subsys *ss;
|
|
|
|
|
|
- /*
|
|
|
- * In general, subsystem has no css->refcnt after pre_destroy(). But
|
|
|
- * in racy cases, subsystem may have to get css->refcnt after
|
|
|
- * pre_destroy() and it makes rmdir return with -EBUSY. This sometimes
|
|
|
- * make rmdir return -EBUSY too often. To avoid that, we use waitqueue
|
|
|
- * for cgroup's rmdir. CGRP_WAIT_ON_RMDIR is for synchronizing rmdir
|
|
|
- * and subsystem's reference count handling. Please see css_get/put
|
|
|
- * and css_tryget() and cgroup_wakeup_rmdir_waiter() implementation.
|
|
|
- */
|
|
|
- set_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
|
|
|
-
|
|
|
/* the vfs holds both inode->i_mutex already */
|
|
|
mutex_lock(&cgroup_mutex);
|
|
|
parent = cgrp->parent;
|
|
|
if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children)) {
|
|
|
- clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
|
|
|
mutex_unlock(&cgroup_mutex);
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
- prepare_to_wait(&cgroup_rmdir_waitq, &wait, TASK_INTERRUPTIBLE);
|
|
|
|
|
|
/*
|
|
|
* Block new css_tryget() by deactivating refcnt and mark @cgrp
|
|
@@ -4114,9 +4067,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
|
|
|
for_each_subsys(cgrp->root, ss)
|
|
|
css_put(cgrp->subsys[ss->subsys_id]);
|
|
|
|
|
|
- finish_wait(&cgroup_rmdir_waitq, &wait);
|
|
|
- clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
|
|
|
-
|
|
|
raw_spin_lock(&release_list_lock);
|
|
|
if (!list_empty(&cgrp->release_list))
|
|
|
list_del_init(&cgrp->release_list);
|
|
@@ -4864,7 +4814,6 @@ void __css_put(struct cgroup_subsys_state *css)
|
|
|
set_bit(CGRP_RELEASABLE, &cgrp->flags);
|
|
|
check_for_release(cgrp);
|
|
|
}
|
|
|
- cgroup_wakeup_rmdir_waiter(cgrp);
|
|
|
break;
|
|
|
case 0:
|
|
|
schedule_work(&css->dput_work);
|