diff options
-rw-r--r-- | kernel/cgroup_freezer.c | 43 |
1 files changed, 11 insertions, 32 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 12bfedb598c2..05d52185139c 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -150,13 +150,6 @@ static void freezer_destroy(struct cgroup *cgroup) | |||
150 | kfree(freezer); | 150 | kfree(freezer); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* task is frozen or will freeze immediately when next it gets woken */ | ||
154 | static bool is_task_frozen_enough(struct task_struct *task) | ||
155 | { | ||
156 | return frozen(task) || | ||
157 | (task_is_stopped_or_traced(task) && freezing(task)); | ||
158 | } | ||
159 | |||
160 | /* | 153 | /* |
161 | * The call to cgroup_lock() in the freezer.state write method prevents | 154 | * The call to cgroup_lock() in the freezer.state write method prevents |
162 | * a write to that file racing against an attach, and hence the | 155 | * a write to that file racing against an attach, and hence the |
@@ -222,7 +215,8 @@ static void update_if_frozen(struct cgroup *cgroup, | |||
222 | cgroup_iter_start(cgroup, &it); | 215 | cgroup_iter_start(cgroup, &it); |
223 | while ((task = cgroup_iter_next(cgroup, &it))) { | 216 | while ((task = cgroup_iter_next(cgroup, &it))) { |
224 | ntotal++; | 217 | ntotal++; |
225 | if (freezing(task) && is_task_frozen_enough(task)) | 218 | if (freezing(task) && (frozen(task) || |
219 | task_is_stopped_or_traced(task))) | ||
226 | nfrozen++; | 220 | nfrozen++; |
227 | } | 221 | } |
228 | 222 | ||
@@ -264,24 +258,15 @@ static int freezer_read(struct cgroup *cgroup, struct cftype *cft, | |||
264 | return 0; | 258 | return 0; |
265 | } | 259 | } |
266 | 260 | ||
267 | static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) | 261 | static void freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) |
268 | { | 262 | { |
269 | struct cgroup_iter it; | 263 | struct cgroup_iter it; |
270 | struct task_struct *task; | 264 | struct task_struct *task; |
271 | unsigned int num_cant_freeze_now = 0; | ||
272 | 265 | ||
273 | cgroup_iter_start(cgroup, &it); | 266 | cgroup_iter_start(cgroup, &it); |
274 | while ((task = cgroup_iter_next(cgroup, &it))) { | 267 | while ((task = cgroup_iter_next(cgroup, &it))) |
275 | if (!freeze_task(task)) | 268 | freeze_task(task); |
276 | continue; | ||
277 | if (is_task_frozen_enough(task)) | ||
278 | continue; | ||
279 | if (!freezing(task) && !freezer_should_skip(task)) | ||
280 | num_cant_freeze_now++; | ||
281 | } | ||
282 | cgroup_iter_end(cgroup, &it); | 269 | cgroup_iter_end(cgroup, &it); |
283 | |||
284 | return num_cant_freeze_now ? -EBUSY : 0; | ||
285 | } | 270 | } |
286 | 271 | ||
287 | static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) | 272 | static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) |
@@ -295,13 +280,10 @@ static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) | |||
295 | cgroup_iter_end(cgroup, &it); | 280 | cgroup_iter_end(cgroup, &it); |
296 | } | 281 | } |
297 | 282 | ||
298 | static int freezer_change_state(struct cgroup *cgroup, | 283 | static void freezer_change_state(struct cgroup *cgroup, |
299 | enum freezer_state goal_state) | 284 | enum freezer_state goal_state) |
300 | { | 285 | { |
301 | struct freezer *freezer; | 286 | struct freezer *freezer = cgroup_freezer(cgroup); |
302 | int retval = 0; | ||
303 | |||
304 | freezer = cgroup_freezer(cgroup); | ||
305 | 287 | ||
306 | spin_lock_irq(&freezer->lock); | 288 | spin_lock_irq(&freezer->lock); |
307 | 289 | ||
@@ -318,22 +300,19 @@ static int freezer_change_state(struct cgroup *cgroup, | |||
318 | if (freezer->state == CGROUP_THAWED) | 300 | if (freezer->state == CGROUP_THAWED) |
319 | atomic_inc(&system_freezing_cnt); | 301 | atomic_inc(&system_freezing_cnt); |
320 | freezer->state = CGROUP_FREEZING; | 302 | freezer->state = CGROUP_FREEZING; |
321 | retval = try_to_freeze_cgroup(cgroup, freezer); | 303 | freeze_cgroup(cgroup, freezer); |
322 | break; | 304 | break; |
323 | default: | 305 | default: |
324 | BUG(); | 306 | BUG(); |
325 | } | 307 | } |
326 | 308 | ||
327 | spin_unlock_irq(&freezer->lock); | 309 | spin_unlock_irq(&freezer->lock); |
328 | |||
329 | return retval; | ||
330 | } | 310 | } |
331 | 311 | ||
332 | static int freezer_write(struct cgroup *cgroup, | 312 | static int freezer_write(struct cgroup *cgroup, |
333 | struct cftype *cft, | 313 | struct cftype *cft, |
334 | const char *buffer) | 314 | const char *buffer) |
335 | { | 315 | { |
336 | int retval; | ||
337 | enum freezer_state goal_state; | 316 | enum freezer_state goal_state; |
338 | 317 | ||
339 | if (strcmp(buffer, freezer_state_strs[CGROUP_THAWED]) == 0) | 318 | if (strcmp(buffer, freezer_state_strs[CGROUP_THAWED]) == 0) |
@@ -345,9 +324,9 @@ static int freezer_write(struct cgroup *cgroup, | |||
345 | 324 | ||
346 | if (!cgroup_lock_live_group(cgroup)) | 325 | if (!cgroup_lock_live_group(cgroup)) |
347 | return -ENODEV; | 326 | return -ENODEV; |
348 | retval = freezer_change_state(cgroup, goal_state); | 327 | freezer_change_state(cgroup, goal_state); |
349 | cgroup_unlock(); | 328 | cgroup_unlock(); |
350 | return retval; | 329 | return 0; |
351 | } | 330 | } |
352 | 331 | ||
353 | static struct cftype files[] = { | 332 | static struct cftype files[] = { |