diff options
author | Paul Menage <menage@google.com> | 2009-01-07 21:07:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 11:31:03 -0500 |
commit | a47295e6bc42ad35f9c15ac66f598aa24debd4e2 (patch) | |
tree | cb765e996ef35ae88e29d60796655d0d35e8cf5e /include | |
parent | e7b80bb695a5b64c92e314838e083b2f3bdf29b2 (diff) |
cgroups: make cgroup_path() RCU-safe
Fix races between /proc/sched_debug by freeing cgroup objects via an RCU
callback. Thus any cgroup reference obtained from an RCU-safe source will
remain valid during the RCU section. Since dentries are also RCU-safe,
this allows us to traverse up the tree safely.
Additionally, make cgroup_path() check for a NULL cgrp->dentry to avoid
trying to report a path for a partially-created cgroup.
[lizf@cn.fujitsu.com: call deactive_super() in cgroup_diput()]
Signed-off-by: Paul Menage <menage@google.com>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Tested-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/cgroup.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index f68dfd8dd53a..73d1c730c3c4 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -116,7 +116,7 @@ struct cgroup { | |||
116 | struct list_head children; /* my children */ | 116 | struct list_head children; /* my children */ |
117 | 117 | ||
118 | struct cgroup *parent; /* my parent */ | 118 | struct cgroup *parent; /* my parent */ |
119 | struct dentry *dentry; /* cgroup fs entry */ | 119 | struct dentry *dentry; /* cgroup fs entry, RCU protected */ |
120 | 120 | ||
121 | /* Private pointers for each registered subsystem */ | 121 | /* Private pointers for each registered subsystem */ |
122 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; | 122 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; |
@@ -145,6 +145,9 @@ struct cgroup { | |||
145 | int pids_use_count; | 145 | int pids_use_count; |
146 | /* Length of the current tasks_pids array */ | 146 | /* Length of the current tasks_pids array */ |
147 | int pids_length; | 147 | int pids_length; |
148 | |||
149 | /* For RCU-protected deletion */ | ||
150 | struct rcu_head rcu_head; | ||
148 | }; | 151 | }; |
149 | 152 | ||
150 | /* A css_set is a structure holding pointers to a set of | 153 | /* A css_set is a structure holding pointers to a set of |