diff options
author | Tejun Heo <tj@kernel.org> | 2012-11-09 12:12:30 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-11-09 12:12:30 -0500 |
commit | a225218060fc8f10ed396c9c8187074697ad044d (patch) | |
tree | d514f4c696ba846a1f63a3e93cc2c7eb093c2312 /kernel/cgroup_freezer.c | |
parent | d6a2fe134219adf94e6bd0c8f6e2a3163ff68c41 (diff) |
cgroup_freezer: introduce CGROUP_FREEZING_[SELF|PARENT]
Introduce FREEZING_SELF and FREEZING_PARENT and make FREEZING OR of
the two flags. This is to prepare for full hierarchy support.
freezer_apply_date() is updated such that it can handle setting and
clearing of both flags. The two flags are also exposed to userland
via read-only files self_freezing and parent_freezing.
Other than the added cgroupfs files, this patch doesn't introduce any
behavior change.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Diffstat (limited to 'kernel/cgroup_freezer.c')
-rw-r--r-- | kernel/cgroup_freezer.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index e76aa9fb3ef4..b8ad93c6f5f6 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -23,8 +23,12 @@ | |||
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | 24 | ||
25 | enum freezer_state_flags { | 25 | enum freezer_state_flags { |
26 | CGROUP_FREEZING = (1 << 1), /* this freezer is freezing */ | 26 | CGROUP_FREEZING_SELF = (1 << 1), /* this freezer is freezing */ |
27 | CGROUP_FREEZING_PARENT = (1 << 2), /* the parent freezer is freezing */ | ||
27 | CGROUP_FROZEN = (1 << 3), /* this and its descendants frozen */ | 28 | CGROUP_FROZEN = (1 << 3), /* this and its descendants frozen */ |
29 | |||
30 | /* mask for all FREEZING flags */ | ||
31 | CGROUP_FREEZING = CGROUP_FREEZING_SELF | CGROUP_FREEZING_PARENT, | ||
28 | }; | 32 | }; |
29 | 33 | ||
30 | struct freezer { | 34 | struct freezer { |
@@ -245,8 +249,13 @@ static void unfreeze_cgroup(struct freezer *freezer) | |||
245 | * freezer_apply_state - apply state change to a single cgroup_freezer | 249 | * freezer_apply_state - apply state change to a single cgroup_freezer |
246 | * @freezer: freezer to apply state change to | 250 | * @freezer: freezer to apply state change to |
247 | * @freeze: whether to freeze or unfreeze | 251 | * @freeze: whether to freeze or unfreeze |
252 | * @state: CGROUP_FREEZING_* flag to set or clear | ||
253 | * | ||
254 | * Set or clear @state on @cgroup according to @freeze, and perform | ||
255 | * freezing or thawing as necessary. | ||
248 | */ | 256 | */ |
249 | static void freezer_apply_state(struct freezer *freezer, bool freeze) | 257 | static void freezer_apply_state(struct freezer *freezer, bool freeze, |
258 | unsigned int state) | ||
250 | { | 259 | { |
251 | /* also synchronizes against task migration, see freezer_attach() */ | 260 | /* also synchronizes against task migration, see freezer_attach() */ |
252 | lockdep_assert_held(&freezer->lock); | 261 | lockdep_assert_held(&freezer->lock); |
@@ -254,13 +263,19 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze) | |||
254 | if (freeze) { | 263 | if (freeze) { |
255 | if (!(freezer->state & CGROUP_FREEZING)) | 264 | if (!(freezer->state & CGROUP_FREEZING)) |
256 | atomic_inc(&system_freezing_cnt); | 265 | atomic_inc(&system_freezing_cnt); |
257 | freezer->state |= CGROUP_FREEZING; | 266 | freezer->state |= state; |
258 | freeze_cgroup(freezer); | 267 | freeze_cgroup(freezer); |
259 | } else { | 268 | } else { |
260 | if (freezer->state & CGROUP_FREEZING) | 269 | bool was_freezing = freezer->state & CGROUP_FREEZING; |
261 | atomic_dec(&system_freezing_cnt); | 270 | |
262 | freezer->state &= ~(CGROUP_FREEZING | CGROUP_FROZEN); | 271 | freezer->state &= ~state; |
263 | unfreeze_cgroup(freezer); | 272 | |
273 | if (!(freezer->state & CGROUP_FREEZING)) { | ||
274 | if (was_freezing) | ||
275 | atomic_dec(&system_freezing_cnt); | ||
276 | freezer->state &= ~CGROUP_FROZEN; | ||
277 | unfreeze_cgroup(freezer); | ||
278 | } | ||
264 | } | 279 | } |
265 | } | 280 | } |
266 | 281 | ||
@@ -275,7 +290,7 @@ static void freezer_change_state(struct freezer *freezer, bool freeze) | |||
275 | { | 290 | { |
276 | /* update @freezer */ | 291 | /* update @freezer */ |
277 | spin_lock_irq(&freezer->lock); | 292 | spin_lock_irq(&freezer->lock); |
278 | freezer_apply_state(freezer, freeze); | 293 | freezer_apply_state(freezer, freeze, CGROUP_FREEZING_SELF); |
279 | spin_unlock_irq(&freezer->lock); | 294 | spin_unlock_irq(&freezer->lock); |
280 | } | 295 | } |
281 | 296 | ||
@@ -295,6 +310,20 @@ static int freezer_write(struct cgroup *cgroup, struct cftype *cft, | |||
295 | return 0; | 310 | return 0; |
296 | } | 311 | } |
297 | 312 | ||
313 | static u64 freezer_self_freezing_read(struct cgroup *cgroup, struct cftype *cft) | ||
314 | { | ||
315 | struct freezer *freezer = cgroup_freezer(cgroup); | ||
316 | |||
317 | return (bool)(freezer->state & CGROUP_FREEZING_SELF); | ||
318 | } | ||
319 | |||
320 | static u64 freezer_parent_freezing_read(struct cgroup *cgroup, struct cftype *cft) | ||
321 | { | ||
322 | struct freezer *freezer = cgroup_freezer(cgroup); | ||
323 | |||
324 | return (bool)(freezer->state & CGROUP_FREEZING_PARENT); | ||
325 | } | ||
326 | |||
298 | static struct cftype files[] = { | 327 | static struct cftype files[] = { |
299 | { | 328 | { |
300 | .name = "state", | 329 | .name = "state", |
@@ -302,6 +331,16 @@ static struct cftype files[] = { | |||
302 | .read_seq_string = freezer_read, | 331 | .read_seq_string = freezer_read, |
303 | .write_string = freezer_write, | 332 | .write_string = freezer_write, |
304 | }, | 333 | }, |
334 | { | ||
335 | .name = "self_freezing", | ||
336 | .flags = CFTYPE_NOT_ON_ROOT, | ||
337 | .read_u64 = freezer_self_freezing_read, | ||
338 | }, | ||
339 | { | ||
340 | .name = "parent_freezing", | ||
341 | .flags = CFTYPE_NOT_ON_ROOT, | ||
342 | .read_u64 = freezer_parent_freezing_read, | ||
343 | }, | ||
305 | { } /* terminate */ | 344 | { } /* terminate */ |
306 | }; | 345 | }; |
307 | 346 | ||