aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup_freezer.c
diff options
context:
space:
mode:
authorMatt Helsley <matthltc@us.ibm.com>2008-10-18 23:27:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 11:52:34 -0400
commit957a4eeaf4af614ab0fc4c09a22593d6ab233f5b (patch)
tree944d338890a2346ca1bd9cd78e01c659635bf085 /kernel/cgroup_freezer.c
parent5a06915c6df9b89cda5ddb3f8cce5f9a6be534d2 (diff)
container freezer: prevent frozen tasks or cgroups from changing
Don't let frozen tasks or cgroups change. This means frozen tasks can't leave their current cgroup for another cgroup. It also means that tasks cannot be added to or removed from a cgroup in the FROZEN state. We enforce these rules by checking for frozen tasks and cgroups in the can_attach() function. Signed-off-by: Matt Helsley <matthltc@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cgroup_freezer.c')
-rw-r--r--kernel/cgroup_freezer.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index b08722de610c..df884022fbd9 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -145,22 +145,40 @@ static void freezer_destroy(struct cgroup_subsys *ss,
145 kfree(cgroup_freezer(cgroup)); 145 kfree(cgroup_freezer(cgroup));
146} 146}
147 147
148/* Task is frozen or will freeze immediately when next it gets woken */
149static bool is_task_frozen_enough(struct task_struct *task)
150{
151 return frozen(task) ||
152 (task_is_stopped_or_traced(task) && freezing(task));
153}
148 154
155/*
156 * The call to cgroup_lock() in the freezer.state write method prevents
157 * a write to that file racing against an attach, and hence the
158 * can_attach() result will remain valid until the attach completes.
159 */
149static int freezer_can_attach(struct cgroup_subsys *ss, 160static int freezer_can_attach(struct cgroup_subsys *ss,
150 struct cgroup *new_cgroup, 161 struct cgroup *new_cgroup,
151 struct task_struct *task) 162 struct task_struct *task)
152{ 163{
153 struct freezer *freezer; 164 struct freezer *freezer;
154 int retval = 0; 165 int retval;
166
167 /* Anything frozen can't move or be moved to/from */
168
169 if (is_task_frozen_enough(task))
170 return -EBUSY;
155 171
156 /*
157 * The call to cgroup_lock() in the freezer.state write method prevents
158 * a write to that file racing against an attach, and hence the
159 * can_attach() result will remain valid until the attach completes.
160 */
161 freezer = cgroup_freezer(new_cgroup); 172 freezer = cgroup_freezer(new_cgroup);
162 if (freezer->state == STATE_FROZEN) 173 if (freezer->state == STATE_FROZEN)
174 return -EBUSY;
175
176 retval = 0;
177 task_lock(task);
178 freezer = task_freezer(task);
179 if (freezer->state == STATE_FROZEN)
163 retval = -EBUSY; 180 retval = -EBUSY;
181 task_unlock(task);
164 return retval; 182 return retval;
165} 183}
166 184
@@ -193,12 +211,7 @@ static void check_if_frozen(struct cgroup *cgroup,
193 cgroup_iter_start(cgroup, &it); 211 cgroup_iter_start(cgroup, &it);
194 while ((task = cgroup_iter_next(cgroup, &it))) { 212 while ((task = cgroup_iter_next(cgroup, &it))) {
195 ntotal++; 213 ntotal++;
196 /* 214 if (is_task_frozen_enough(task))
197 * Task is frozen or will freeze immediately when next it gets
198 * woken
199 */
200 if (frozen(task) ||
201 (task_is_stopped_or_traced(task) && freezing(task)))
202 nfrozen++; 215 nfrozen++;
203 } 216 }
204 217
@@ -249,11 +262,7 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
249 while ((task = cgroup_iter_next(cgroup, &it))) { 262 while ((task = cgroup_iter_next(cgroup, &it))) {
250 if (!freeze_task(task, true)) 263 if (!freeze_task(task, true))
251 continue; 264 continue;
252 if (task_is_stopped_or_traced(task) && freezing(task)) 265 if (is_task_frozen_enough(task))
253 /*
254 * The freeze flag is set so these tasks will
255 * immediately go into the fridge upon waking.
256 */
257 continue; 266 continue;
258 if (!freezing(task) && !freezer_should_skip(task)) 267 if (!freezing(task) && !freezer_should_skip(task))
259 num_cant_freeze_now++; 268 num_cant_freeze_now++;