Now that mem_cgroup_pre_destroy callback doesn't fail finally we can
safely move on and forbit all the callbacks to fail. The last missing
piece is moving cgroup_call_pre_destroy after cgroup_clear_css_refs so
that css_tryget fails so no new charges for the memcg can happen.
The callbacks are also called from within cgroup_lock to guarantee that
no new tasks show up. We could theoretically call them outside of the
lock but then we have to move after CGRP_REMOVED flag is set.

Signed-off-by: Michal Hocko <mho...@suse.cz>
---
 kernel/cgroup.c |   30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index b7d9606..00729c1 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -855,7 +855,7 @@ static struct inode *cgroup_new_inode(umode_t mode, struct 
super_block *sb)
  * Call subsys's pre_destroy handler.
  * This is called before css refcnt check.
  */
-static int cgroup_call_pre_destroy(struct cgroup *cgrp)
+static void cgroup_call_pre_destroy(struct cgroup *cgrp)
 {
        struct cgroup_subsys *ss;
        int ret = 0;
@@ -864,15 +864,8 @@ static int cgroup_call_pre_destroy(struct cgroup *cgrp)
                if (!ss->pre_destroy)
                        continue;
 
-               ret = ss->pre_destroy(cgrp);
-               if (ret) {
-                       /* ->pre_destroy() failure is being deprecated */
-                       WARN_ON_ONCE(!ss->__DEPRECATED_clear_css_refs);
-                       break;
-               }
+               BUG_ON(ss->pre_destroy(cgrp));
        }
-
-       return ret;
 }
 
 static void cgroup_diput(struct dentry *dentry, struct inode *inode)
@@ -4161,7 +4154,6 @@ again:
                mutex_unlock(&cgroup_mutex);
                return -EBUSY;
        }
-       mutex_unlock(&cgroup_mutex);
 
        /*
         * In general, subsystem has no css->refcnt after pre_destroy(). But
@@ -4174,17 +4166,6 @@ again:
         */
        set_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
 
-       /*
-        * Call pre_destroy handlers of subsys. Notify subsystems
-        * that rmdir() request comes.
-        */
-       ret = cgroup_call_pre_destroy(cgrp);
-       if (ret) {
-               clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
-               return ret;
-       }
-
-       mutex_lock(&cgroup_mutex);
        parent = cgrp->parent;
        if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children)) {
                clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
@@ -4206,6 +4187,13 @@ again:
                        return -EINTR;
                goto again;
        }
+
+       /*
+        * Call pre_destroy handlers of subsys. Notify subsystems
+        * that rmdir() request comes.
+        */
+       cgroup_call_pre_destroy(cgrp);
+
        /* NO css_tryget() can success after here. */
        finish_wait(&cgroup_rmdir_waitq, &wait);
        clear_bit(CGRP_WAIT_ON_RMDIR, &cgrp->flags);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to