]> git.openfabrics.org - ~shefty/rdma-dev.git/blobdiff - kernel/cgroup.c
cgroup: kill cgroup_subsys->__DEPRECATED_clear_css_refs
[~shefty/rdma-dev.git] / kernel / cgroup.c
index 79818507e444aa3050c9994841258292c294bd2e..8c605e2bdd1ae45698e45b96ebcd8f2ca489726c 100644 (file)
@@ -865,11 +865,8 @@ static int cgroup_call_pre_destroy(struct cgroup *cgrp)
                        continue;
 
                ret = ss->pre_destroy(cgrp);
-               if (ret) {
-                       /* ->pre_destroy() failure is being deprecated */
-                       WARN_ON_ONCE(!ss->__DEPRECATED_clear_css_refs);
+               if (WARN_ON_ONCE(ret))
                        break;
-               }
        }
 
        return ret;
@@ -3901,14 +3898,12 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
        cgrp->subsys[ss->subsys_id] = css;
 
        /*
-        * If !clear_css_refs, css holds an extra ref to @cgrp->dentry
-        * which is put on the last css_put().  dput() requires process
-        * context, which css_put() may be called without.  @css->dput_work
-        * will be used to invoke dput() asynchronously from css_put().
+        * css holds an extra ref to @cgrp->dentry which is put on the last
+        * css_put().  dput() requires process context, which css_put() may
+        * be called without.  @css->dput_work will be used to invoke
+        * dput() asynchronously from css_put().
         */
        INIT_WORK(&css->dput_work, css_dput_fn);
-       if (ss->__DEPRECATED_clear_css_refs)
-               set_bit(CSS_CLEAR_CSS_REFS, &css->flags);
 }
 
 /*
@@ -3978,10 +3973,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
        if (err < 0)
                goto err_remove;
 
-       /* If !clear_css_refs, each css holds a ref to the cgroup's dentry */
+       /* each css holds a ref to the cgroup's dentry */
        for_each_subsys(root, ss)
-               if (!ss->__DEPRECATED_clear_css_refs)
-                       dget(dentry);
+               dget(dentry);
 
        /* The cgroup directory was pre-locked for us */
        BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex));
@@ -4066,71 +4060,6 @@ static int cgroup_has_css_refs(struct cgroup *cgrp)
        return 0;
 }
 
-/*
- * Atomically mark all (or else none) of the cgroup's CSS objects as
- * CSS_REMOVED. Return true on success, or false if the cgroup has
- * busy subsystems. Call with cgroup_mutex held
- *
- * Depending on whether a subsys has __DEPRECATED_clear_css_refs set or
- * not, cgroup removal behaves differently.
- *
- * If clear is set, css refcnt for the subsystem should be zero before
- * cgroup removal can be committed.  This is implemented by
- * CGRP_WAIT_ON_RMDIR and retry logic around ->pre_destroy(), which may be
- * called multiple times until all css refcnts reach zero and is allowed to
- * veto removal on any invocation.  This behavior is deprecated and will be
- * removed as soon as the existing user (memcg) is updated.
- *
- * If clear is not set, each css holds an extra reference to the cgroup's
- * dentry and cgroup removal proceeds regardless of css refs.
- * ->pre_destroy() will be called at least once and is not allowed to fail.
- * On the last put of each css, whenever that may be, the extra dentry ref
- * is put so that dentry destruction happens only after all css's are
- * released.
- */
-static int cgroup_clear_css_refs(struct cgroup *cgrp)
-{
-       struct cgroup_subsys *ss;
-       unsigned long flags;
-       bool failed = false;
-
-       local_irq_save(flags);
-
-       /*
-        * Block new css_tryget() by deactivating refcnt.  If all refcnts
-        * for subsystems w/ clear_css_refs set were 1 at the moment of
-        * deactivation, we succeeded.
-        */
-       for_each_subsys(cgrp->root, ss) {
-               struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
-
-               WARN_ON(atomic_read(&css->refcnt) < 0);
-               atomic_add(CSS_DEACT_BIAS, &css->refcnt);
-
-               if (ss->__DEPRECATED_clear_css_refs)
-                       failed |= css_refcnt(css) != 1;
-       }
-
-       /*
-        * If succeeded, set REMOVED and put all the base refs; otherwise,
-        * restore refcnts to positive values.  Either way, all in-progress
-        * css_tryget() will be released.
-        */
-       for_each_subsys(cgrp->root, ss) {
-               struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
-
-               if (!failed) {
-                       set_bit(CSS_REMOVED, &css->flags);
-                       css_put(css);
-               } else {
-                       atomic_sub(CSS_DEACT_BIAS, &css->refcnt);
-               }
-       }
-
-       local_irq_restore(flags);
-       return !failed;
-}
-
 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
 {
        struct cgroup *cgrp = dentry->d_fsdata;
@@ -4138,10 +4067,10 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
        struct cgroup *parent;
        DEFINE_WAIT(wait);
        struct cgroup_event *event, *tmp;
+       struct cgroup_subsys *ss;
        int ret;
 
        /* the vfs holds both inode->i_mutex already */
-again:
        mutex_lock(&cgroup_mutex);
        if (atomic_read(&cgrp->count) != 0) {
                mutex_unlock(&cgroup_mutex);
@@ -4182,21 +4111,34 @@ again:
                return -EBUSY;
        }
        prepare_to_wait(&cgroup_rmdir_waitq, &wait, TASK_INTERRUPTIBLE);
-       if (!cgroup_clear_css_refs(cgrp)) {
-               mutex_unlock(&cgroup_mutex);
-               /*
-                * Because someone may call cgroup_wakeup_rmdir_waiter() before
-                * prepare_to_wait(), we need to check this flag.
-                */
-               if (test_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags))
-                       schedule();
-               finish_wait(&cgroup_rmdir_waitq, &wait);
-               clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
-               if (signal_pending(current))
-                       return -EINTR;
-               goto again;
+
+       local_irq_disable();
+
+       /* block new css_tryget() by deactivating refcnt */
+       for_each_subsys(cgrp->root, ss) {
+               struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
+
+               WARN_ON(atomic_read(&css->refcnt) < 0);
+               atomic_add(CSS_DEACT_BIAS, &css->refcnt);
+       }
+
+       /*
+        * Set REMOVED.  All in-progress css_tryget() will be released.
+        * Put all the base refs.  Each css holds an extra reference to the
+        * cgroup's dentry and cgroup removal proceeds regardless of css
+        * refs.  On the last put of each css, whenever that may be, the
+        * extra dentry ref is put so that dentry destruction happens only
+        * after all css's are released.
+        */
+       for_each_subsys(cgrp->root, ss) {
+               struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
+
+               set_bit(CSS_REMOVED, &css->flags);
+               css_put(css);
        }
-       /* NO css_tryget() can success after here. */
+
+       local_irq_enable();
+
        finish_wait(&cgroup_rmdir_waitq, &wait);
        clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
 
@@ -4949,8 +4891,7 @@ void __css_put(struct cgroup_subsys_state *css)
                cgroup_wakeup_rmdir_waiter(cgrp);
                break;
        case 0:
-               if (!test_bit(CSS_CLEAR_CSS_REFS, &css->flags))
-                       schedule_work(&css->dput_work);
+               schedule_work(&css->dput_work);
                break;
        }
        rcu_read_unlock();