]> Pileus Git - ~andy/linux/blobdiff - kernel/cgroup.c
reciprocal_divide: update/correction of the algorithm
[~andy/linux] / kernel / cgroup.c
index bcb1755f410a6b79538af66c016b55dbb06efb4f..bc1dcabe92176636baf79c7ef52e597422aeaf75 100644 (file)
@@ -890,6 +890,16 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)
                struct cgroup *cgrp = dentry->d_fsdata;
 
                BUG_ON(!(cgroup_is_dead(cgrp)));
+
+               /*
+                * XXX: cgrp->id is only used to look up css's.  As cgroup
+                * and css's lifetimes will be decoupled, it should be made
+                * per-subsystem and moved to css->id so that lookups are
+                * successful until the target css is released.
+                */
+               idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
+               cgrp->id = -1;
+
                call_rcu(&cgrp->rcu_head, cgroup_free_rcu);
        } else {
                struct cfent *cfe = __d_cfe(dentry);
@@ -4268,6 +4278,7 @@ static void css_release(struct percpu_ref *ref)
        struct cgroup_subsys_state *css =
                container_of(ref, struct cgroup_subsys_state, refcnt);
 
+       rcu_assign_pointer(css->cgroup->subsys[css->ss->subsys_id], NULL);
        call_rcu(&css->rcu_head, css_free_rcu_fn);
 }
 
@@ -4733,14 +4744,6 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp)
        /* delete this cgroup from parent->children */
        list_del_rcu(&cgrp->sibling);
 
-       /*
-        * We should remove the cgroup object from idr before its grace
-        * period starts, so we won't be looking up a cgroup while the
-        * cgroup is being freed.
-        */
-       idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
-       cgrp->id = -1;
-
        dput(d);
 
        set_bit(CGRP_RELEASABLE, &parent->flags);