diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2008-10-18 23:28:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 11:52:38 -0400 |
commit | 146aa1bd0511f88ddb4e92fafa2b8aad4f2f65f3 (patch) | |
tree | d7deb46b9a38f82f109b2126317899efbbce41c2 /kernel/cgroup_debug.c | |
parent | 248736c2a57206388c86f8cdd3392ee986e84f9f (diff) |
cgroups: fix probable race with put_css_set[_taskexit] and find_css_set
put_css_set_taskexit may be called when find_css_set is called on other
cpu. And the race will occur:
put_css_set_taskexit side find_css_set side
|
atomic_dec_and_test(&kref->refcount) |
/* kref->refcount = 0 */ |
....................................................................
| read_lock(&css_set_lock)
| find_existing_css_set
| get_css_set
| read_unlock(&css_set_lock);
....................................................................
__release_css_set |
....................................................................
| /* use a released css_set */
|
[put_css_set is the same. But in the current code, all put_css_set are
put into cgroup mutex critical region as the same as find_css_set.]
[akpm@linux-foundation.org: repair comments]
[menage@google.com: eliminate race in css_set refcounting]
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Paul Menage <menage@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cgroup_debug.c')
-rw-r--r-- | kernel/cgroup_debug.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c index c3dc3aba4c02..daca6209202d 100644 --- a/kernel/cgroup_debug.c +++ b/kernel/cgroup_debug.c | |||
@@ -57,7 +57,7 @@ static u64 current_css_set_refcount_read(struct cgroup *cont, | |||
57 | u64 count; | 57 | u64 count; |
58 | 58 | ||
59 | rcu_read_lock(); | 59 | rcu_read_lock(); |
60 | count = atomic_read(¤t->cgroups->ref.refcount); | 60 | count = atomic_read(¤t->cgroups->refcount); |
61 | rcu_read_unlock(); | 61 | rcu_read_unlock(); |
62 | return count; | 62 | return count; |
63 | } | 63 | } |
@@ -90,7 +90,7 @@ static struct cftype files[] = { | |||
90 | { | 90 | { |
91 | .name = "releasable", | 91 | .name = "releasable", |
92 | .read_u64 = releasable_read, | 92 | .read_u64 = releasable_read, |
93 | } | 93 | }, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont) | 96 | static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont) |