aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/cgroup.h
diff options
context:
space:
mode:
authorBen Blum <bblum@google.com>2009-09-23 18:56:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-24 10:20:58 -0400
commit72a8cb30d10d4041c455a7054607a7d519167c87 (patch)
tree9b499f9c7f4de011ba5c8282df0b2280b7c21f0b /include/linux/cgroup.h
parent102a775e3647628727ae83a9a6abf0564c3ca7cb (diff)
cgroups: ensure correct concurrent opening/reading of pidlists across pid namespaces
Previously there was the problem in which two processes from different pid namespaces reading the tasks or procs file could result in one process seeing results from the other's namespace. Rather than one pidlist for each file in a cgroup, we now keep a list of pidlists keyed by namespace and file type (tasks versus procs) in which entries are placed on demand. Each pidlist has its own lock, and that the pidlists themselves are passed around in the seq_file's private pointer means we don't have to touch the cgroup or its master list except when creating and destroying entries. Signed-off-by: Ben Blum <bblum@google.com> Signed-off-by: Paul Menage <menage@google.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Matt Helsley <matthltc@us.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r--include/linux/cgroup.h34
1 files changed, 29 insertions, 5 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 2357733a0a80..88e863460726 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -141,15 +141,36 @@ enum {
141 CGRP_WAIT_ON_RMDIR, 141 CGRP_WAIT_ON_RMDIR,
142}; 142};
143 143
144/* which pidlist file are we talking about? */
145enum cgroup_filetype {
146 CGROUP_FILE_PROCS,
147 CGROUP_FILE_TASKS,
148};
149
150/*
151 * A pidlist is a list of pids that virtually represents the contents of one
152 * of the cgroup files ("procs" or "tasks"). We keep a list of such pidlists,
153 * a pair (one each for procs, tasks) for each pid namespace that's relevant
154 * to the cgroup.
155 */
144struct cgroup_pidlist { 156struct cgroup_pidlist {
145 /* protects the other fields */ 157 /*
146 struct rw_semaphore mutex; 158 * used to find which pidlist is wanted. doesn't change as long as
159 * this particular list stays in the list.
160 */
161 struct { enum cgroup_filetype type; struct pid_namespace *ns; } key;
147 /* array of xids */ 162 /* array of xids */
148 pid_t *list; 163 pid_t *list;
149 /* how many elements the above list has */ 164 /* how many elements the above list has */
150 int length; 165 int length;
151 /* how many files are using the current array */ 166 /* how many files are using the current array */
152 int use_count; 167 int use_count;
168 /* each of these stored in a list by its cgroup */
169 struct list_head links;
170 /* pointer to the cgroup we belong to, for list removal purposes */
171 struct cgroup *owner;
172 /* protects the other fields */
173 struct rw_semaphore mutex;
153}; 174};
154 175
155struct cgroup { 176struct cgroup {
@@ -190,9 +211,12 @@ struct cgroup {
190 */ 211 */
191 struct list_head release_list; 212 struct list_head release_list;
192 213
193 /* we will have two separate pidlists, one for pids (the tasks file) 214 /*
194 * and one for tgids (the procs file). */ 215 * list of pidlists, up to two for each namespace (one for procs, one
195 struct cgroup_pidlist tasks, procs; 216 * for tasks); created on demand.
217 */
218 struct list_head pidlists;
219 struct mutex pidlist_mutex;
196 220
197 /* For RCU-protected deletion */ 221 /* For RCU-protected deletion */
198 struct rcu_head rcu_head; 222 struct rcu_head rcu_head;