aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-19 11:13:36 -0500
committerTejun Heo <tj@kernel.org>2012-11-19 11:13:36 -0500
commitfebfcef60d4f9457785b45aab548bc7ee5ea158f (patch)
tree70fab0e8ec07aec4142f1dc228f307e6b1d79de0 /kernel/cgroup.c
parent4e139afc22cb98d0d032ffce0285bfcc73ca5217 (diff)
cgroup: cgroup->dentry isn't a RCU pointer
cgroup->dentry is marked and used as a RCU pointer; however, it isn't one - the final dentry put doesn't go through call_rcu(). cgroup and dentry share the same RCU freeing rule via synchronize_rcu() in cgroup_diput() (kfree_rcu() used on cgrp is unnecessary). If cgrp is accessible under RCU read lock, so is its dentry and dereferencing cgrp->dentry doesn't need any further RCU protection or annotation. While not being accurate, before the previous patch, the RCU accessors served a purpose as memory barriers - cgroup->dentry used to be assigned after the cgroup was made visible to cgroup_path(), so the assignment and dereferencing in cgroup_path() needed the memory barrier pair. Now that list_add_tail_rcu() happens after cgroup->dentry is assigned, this no longer is necessary. Remove the now unnecessary and misleading RCU annotations from cgroup->dentry. To make up for the removal of rcu_dereference_check() in cgroup_path(), add an explicit rcu_lockdep_assert(), which asserts the dereference rule of @cgrp, not cgrp->dentry. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index d62a529db2f7..affc76d7f739 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1756,9 +1756,11 @@ static struct kobject *cgroup_kobj;
1756 */ 1756 */
1757int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) 1757int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
1758{ 1758{
1759 struct dentry *dentry = cgrp->dentry;
1759 char *start; 1760 char *start;
1760 struct dentry *dentry = rcu_dereference_check(cgrp->dentry, 1761
1761 cgroup_lock_is_held()); 1762 rcu_lockdep_assert(rcu_read_lock_held() || cgroup_lock_is_held(),
1763 "cgroup_path() called without proper locking");
1762 1764
1763 if (!dentry || cgrp == dummytop) { 1765 if (!dentry || cgrp == dummytop) {
1764 /* 1766 /*
@@ -1782,8 +1784,7 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
1782 if (!cgrp) 1784 if (!cgrp)
1783 break; 1785 break;
1784 1786
1785 dentry = rcu_dereference_check(cgrp->dentry, 1787 dentry = cgrp->dentry;
1786 cgroup_lock_is_held());
1787 if (!cgrp->parent) 1788 if (!cgrp->parent)
1788 continue; 1789 continue;
1789 if (--start < buf) 1790 if (--start < buf)
@@ -4124,7 +4125,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4124 4125
4125 /* allocation complete, commit to creation */ 4126 /* allocation complete, commit to creation */
4126 dentry->d_fsdata = cgrp; 4127 dentry->d_fsdata = cgrp;
4127 rcu_assign_pointer(cgrp->dentry, dentry); 4128 cgrp->dentry = dentry;
4128 list_add_tail(&cgrp->allcg_node, &root->allcg_list); 4129 list_add_tail(&cgrp->allcg_node, &root->allcg_list);
4129 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); 4130 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children);
4130 root->number_of_cgroups++; 4131 root->number_of_cgroups++;