aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup_freezer.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-09 12:12:30 -0500
committerTejun Heo <tj@kernel.org>2012-11-09 12:12:30 -0500
commita225218060fc8f10ed396c9c8187074697ad044d (patch)
treed514f4c696ba846a1f63a3e93cc2c7eb093c2312 /kernel/cgroup_freezer.c
parentd6a2fe134219adf94e6bd0c8f6e2a3163ff68c41 (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.c55
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
25enum freezer_state_flags { 25enum 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
30struct freezer { 34struct 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 */
249static void freezer_apply_state(struct freezer *freezer, bool freeze) 257static 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
313static 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
320static 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
298static struct cftype files[] = { 327static 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