diff options
author | Tejun Heo <tj@kernel.org> | 2013-06-21 18:52:33 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-06-26 13:48:48 -0400 |
commit | a4ea1cc90604df08d471ae84eb9627319d10c844 (patch) | |
tree | 73e12ef6845c5cf5bac0b8a2e4e6c4dd03af0a1b /kernel/cgroup.c | |
parent | a8ad805cfde00be8fe3b3dae8890996dbeb91e2c (diff) |
cgroup: always use RCU accessors for protected accesses
kernel/cgroup.c still has places where a RCU pointer is set and
accessed directly without going through RCU_INIT_POINTER() or
rcu_dereference_protected(). They're all properly protected accesses
so nothing is broken but it leads to spurious sparse RCU address space
warnings.
Substitute direct accesses with RCU_INIT_POINTER() and
rcu_dereference_protected(). Note that %true is specified as the
extra condition for all derference updates. This isn't ideal as all
it does is suppressing warning without actually policing
synchronization rules; however, most are scheduled to be removed
pretty soon along with css_id itself, so no reason to be more
elaborate.
Combined with the previous changes, this removes all RCU related
sparse warnings from cgroup.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Acked-by; Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ee9f0c1c8bff..4ed86773fff7 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1427,7 +1427,7 @@ static void init_cgroup_root(struct cgroupfs_root *root) | |||
1427 | INIT_LIST_HEAD(&root->root_list); | 1427 | INIT_LIST_HEAD(&root->root_list); |
1428 | root->number_of_cgroups = 1; | 1428 | root->number_of_cgroups = 1; |
1429 | cgrp->root = root; | 1429 | cgrp->root = root; |
1430 | cgrp->name = &root_cgroup_name; | 1430 | RCU_INIT_POINTER(cgrp->name, &root_cgroup_name); |
1431 | init_cgroup_housekeeping(cgrp); | 1431 | init_cgroup_housekeeping(cgrp); |
1432 | } | 1432 | } |
1433 | 1433 | ||
@@ -2558,7 +2558,7 @@ static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2558 | return ret; | 2558 | return ret; |
2559 | } | 2559 | } |
2560 | 2560 | ||
2561 | old_name = cgrp->name; | 2561 | old_name = rcu_dereference_protected(cgrp->name, true); |
2562 | rcu_assign_pointer(cgrp->name, name); | 2562 | rcu_assign_pointer(cgrp->name, name); |
2563 | 2563 | ||
2564 | kfree_rcu(old_name, rcu_head); | 2564 | kfree_rcu(old_name, rcu_head); |
@@ -4177,13 +4177,15 @@ static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files, | |||
4177 | /* This cgroup is ready now */ | 4177 | /* This cgroup is ready now */ |
4178 | for_each_root_subsys(cgrp->root, ss) { | 4178 | for_each_root_subsys(cgrp->root, ss) { |
4179 | struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id]; | 4179 | struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id]; |
4180 | struct css_id *id = rcu_dereference_protected(css->id, true); | ||
4181 | |||
4180 | /* | 4182 | /* |
4181 | * Update id->css pointer and make this css visible from | 4183 | * Update id->css pointer and make this css visible from |
4182 | * CSS ID functions. This pointer will be dereferened | 4184 | * CSS ID functions. This pointer will be dereferened |
4183 | * from RCU-read-side without locks. | 4185 | * from RCU-read-side without locks. |
4184 | */ | 4186 | */ |
4185 | if (css->id) | 4187 | if (id) |
4186 | rcu_assign_pointer(css->id->css, css); | 4188 | rcu_assign_pointer(id->css, css); |
4187 | } | 4189 | } |
4188 | 4190 | ||
4189 | return 0; | 4191 | return 0; |
@@ -4863,7 +4865,7 @@ int __init cgroup_init_early(void) | |||
4863 | css_set_count = 1; | 4865 | css_set_count = 1; |
4864 | init_cgroup_root(&cgroup_dummy_root); | 4866 | init_cgroup_root(&cgroup_dummy_root); |
4865 | cgroup_root_count = 1; | 4867 | cgroup_root_count = 1; |
4866 | init_task.cgroups = &init_css_set; | 4868 | RCU_INIT_POINTER(init_task.cgroups, &init_css_set); |
4867 | 4869 | ||
4868 | init_cgrp_cset_link.cset = &init_css_set; | 4870 | init_cgrp_cset_link.cset = &init_css_set; |
4869 | init_cgrp_cset_link.cgrp = cgroup_dummy_top; | 4871 | init_cgrp_cset_link.cgrp = cgroup_dummy_top; |
@@ -5380,7 +5382,8 @@ bool css_is_ancestor(struct cgroup_subsys_state *child, | |||
5380 | 5382 | ||
5381 | void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css) | 5383 | void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css) |
5382 | { | 5384 | { |
5383 | struct css_id *id = css->id; | 5385 | struct css_id *id = rcu_dereference_protected(css->id, true); |
5386 | |||
5384 | /* When this is called before css_id initialization, id can be NULL */ | 5387 | /* When this is called before css_id initialization, id can be NULL */ |
5385 | if (!id) | 5388 | if (!id) |
5386 | return; | 5389 | return; |
@@ -5446,8 +5449,8 @@ static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss, | |||
5446 | return PTR_ERR(newid); | 5449 | return PTR_ERR(newid); |
5447 | 5450 | ||
5448 | newid->stack[0] = newid->id; | 5451 | newid->stack[0] = newid->id; |
5449 | newid->css = rootcss; | 5452 | RCU_INIT_POINTER(newid->css, rootcss); |
5450 | rootcss->id = newid; | 5453 | RCU_INIT_POINTER(rootcss->id, newid); |
5451 | return 0; | 5454 | return 0; |
5452 | } | 5455 | } |
5453 | 5456 | ||
@@ -5461,7 +5464,7 @@ static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent, | |||
5461 | subsys_id = ss->subsys_id; | 5464 | subsys_id = ss->subsys_id; |
5462 | parent_css = parent->subsys[subsys_id]; | 5465 | parent_css = parent->subsys[subsys_id]; |
5463 | child_css = child->subsys[subsys_id]; | 5466 | child_css = child->subsys[subsys_id]; |
5464 | parent_id = parent_css->id; | 5467 | parent_id = rcu_dereference_protected(parent_css->id, true); |
5465 | depth = parent_id->depth + 1; | 5468 | depth = parent_id->depth + 1; |
5466 | 5469 | ||
5467 | child_id = get_new_cssid(ss, depth); | 5470 | child_id = get_new_cssid(ss, depth); |