diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 3a53c771e503..6db8b7f297a1 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4435,7 +4435,15 @@ __setup("cgroup_disable=", cgroup_disable); | |||
4435 | */ | 4435 | */ |
4436 | unsigned short css_id(struct cgroup_subsys_state *css) | 4436 | unsigned short css_id(struct cgroup_subsys_state *css) |
4437 | { | 4437 | { |
4438 | struct css_id *cssid = rcu_dereference(css->id); | 4438 | struct css_id *cssid; |
4439 | |||
4440 | /* | ||
4441 | * This css_id() can return correct value when somone has refcnt | ||
4442 | * on this or this is under rcu_read_lock(). Once css->id is allocated, | ||
4443 | * it's unchanged until freed. | ||
4444 | */ | ||
4445 | cssid = rcu_dereference_check(css->id, | ||
4446 | rcu_read_lock_held() || atomic_read(&css->refcnt)); | ||
4439 | 4447 | ||
4440 | if (cssid) | 4448 | if (cssid) |
4441 | return cssid->id; | 4449 | return cssid->id; |
@@ -4445,7 +4453,10 @@ EXPORT_SYMBOL_GPL(css_id); | |||
4445 | 4453 | ||
4446 | unsigned short css_depth(struct cgroup_subsys_state *css) | 4454 | unsigned short css_depth(struct cgroup_subsys_state *css) |
4447 | { | 4455 | { |
4448 | struct css_id *cssid = rcu_dereference(css->id); | 4456 | struct css_id *cssid; |
4457 | |||
4458 | cssid = rcu_dereference_check(css->id, | ||
4459 | rcu_read_lock_held() || atomic_read(&css->refcnt)); | ||
4449 | 4460 | ||
4450 | if (cssid) | 4461 | if (cssid) |
4451 | return cssid->depth; | 4462 | return cssid->depth; |