[PATCH 4/8] cgroup: move cgroup->kn->priv clearing to cgroup_rmdir()
The ->priv field of a cgroup directory kernfs_node points back to the cgroup. This field is RCU cleared in cgroup_destroy_locked() for non-kernfs accesses from css_tryget_from_dir() and cgroupstats_build(). As these are only applicable to cgroups which finished creation successfully and fully initialized cgroups are always removed by cgroup_rmdir(), this can be safely moved to the end of cgroup_rmdir(). This will help simplifying cgroup locking and shouldn't introduce any behavior difference. Signed-off-by: Tejun Heo --- kernel/cgroup.c | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f544e46..3118a63 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4547,17 +4547,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) /* remove @cgrp directory along with the base files */ mutex_unlock(_mutex); - - /* -* There are two control paths which try to determine cgroup from -* dentry without going through kernfs - cgroupstats_build() and -* css_tryget_from_dir(). Those are supported by RCU protecting -* clearing of cgrp->kn->priv backpointer, which should happen -* after all files under it have been removed. -*/ kernfs_remove(cgrp->kn);/* @cgrp has an extra ref on its kn */ - RCU_INIT_POINTER(*(void __rcu __force **)>kn->priv, NULL); - mutex_lock(_mutex); return 0; @@ -4616,6 +4606,17 @@ static int cgroup_rmdir(struct kernfs_node *kn) mutex_unlock(_tree_mutex); kernfs_unbreak_active_protection(kn); + + /* +* There are two control paths which try to determine cgroup from +* dentry without going through kernfs - cgroupstats_build() and +* css_tryget_from_dir(). Those are supported by RCU protecting +* clearing of kn->priv backpointer, which should happen after all +* files under it have been removed. +*/ + if (!ret) + RCU_INIT_POINTER(*(void __rcu __force **)>priv, NULL); + cgroup_put(cgrp); return ret; } @@ -5175,7 +5176,7 @@ struct cgroup_subsys_state *css_tryget_from_dir(struct dentry *dentry, /* * This path doesn't originate from kernfs and @kn could already * have been or be removed at any point. @kn->priv is RCU -* protected for this access. See destroy_locked() for details. +* protected for this access. See cgroup_rmdir() for details. */ cgrp = rcu_dereference(kn->priv); if (cgrp) -- 1.9.0 -- 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/
[PATCH 4/8] cgroup: move cgroup-kn-priv clearing to cgroup_rmdir()
The -priv field of a cgroup directory kernfs_node points back to the cgroup. This field is RCU cleared in cgroup_destroy_locked() for non-kernfs accesses from css_tryget_from_dir() and cgroupstats_build(). As these are only applicable to cgroups which finished creation successfully and fully initialized cgroups are always removed by cgroup_rmdir(), this can be safely moved to the end of cgroup_rmdir(). This will help simplifying cgroup locking and shouldn't introduce any behavior difference. Signed-off-by: Tejun Heo t...@kernel.org --- kernel/cgroup.c | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f544e46..3118a63 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4547,17 +4547,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) /* remove @cgrp directory along with the base files */ mutex_unlock(cgroup_mutex); - - /* -* There are two control paths which try to determine cgroup from -* dentry without going through kernfs - cgroupstats_build() and -* css_tryget_from_dir(). Those are supported by RCU protecting -* clearing of cgrp-kn-priv backpointer, which should happen -* after all files under it have been removed. -*/ kernfs_remove(cgrp-kn);/* @cgrp has an extra ref on its kn */ - RCU_INIT_POINTER(*(void __rcu __force **)cgrp-kn-priv, NULL); - mutex_lock(cgroup_mutex); return 0; @@ -4616,6 +4606,17 @@ static int cgroup_rmdir(struct kernfs_node *kn) mutex_unlock(cgroup_tree_mutex); kernfs_unbreak_active_protection(kn); + + /* +* There are two control paths which try to determine cgroup from +* dentry without going through kernfs - cgroupstats_build() and +* css_tryget_from_dir(). Those are supported by RCU protecting +* clearing of kn-priv backpointer, which should happen after all +* files under it have been removed. +*/ + if (!ret) + RCU_INIT_POINTER(*(void __rcu __force **)kn-priv, NULL); + cgroup_put(cgrp); return ret; } @@ -5175,7 +5176,7 @@ struct cgroup_subsys_state *css_tryget_from_dir(struct dentry *dentry, /* * This path doesn't originate from kernfs and @kn could already * have been or be removed at any point. @kn-priv is RCU -* protected for this access. See destroy_locked() for details. +* protected for this access. See cgroup_rmdir() for details. */ cgrp = rcu_dereference(kn-priv); if (cgrp) -- 1.9.0 -- 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/