17 #include <linux/export.h>
18 #include <linux/slab.h>
32 struct cgroup_subsys_state
css;
37 static inline struct freezer *cgroup_freezer(
38 struct cgroup *cgroup)
41 cgroup_subsys_state(cgroup, freezer_subsys_id),
47 return container_of(task_subsys_state(task, freezer_subsys_id),
57 state = task_freezer(task)->state;
68 static const char *freezer_state_strs[] = {
131 static struct cgroup_subsys_state *freezer_create(
struct cgroup *cgroup)
135 freezer = kzalloc(
sizeof(
struct freezer),
GFP_KERNEL);
141 return &freezer->
css;
144 static void freezer_destroy(
struct cgroup *cgroup)
146 struct freezer *freezer = cgroup_freezer(cgroup);
154 static bool is_task_frozen_enough(
struct task_struct *task)
156 return frozen(task) ||
165 static int freezer_can_attach(
struct cgroup *new_cgroup,
168 struct freezer *freezer;
174 cgroup_taskset_for_each(task, new_cgroup, tset)
178 freezer = cgroup_freezer(new_cgroup);
187 struct freezer *freezer;
197 freezer = task_freezer(task);
204 if (!freezer->
css.cgroup->parent)
207 spin_lock_irq(&freezer->
lock);
213 spin_unlock_irq(&freezer->
lock);
219 static void update_if_frozen(
struct cgroup *cgroup,
220 struct freezer *freezer)
222 struct cgroup_iter it;
224 unsigned int nfrozen = 0, ntotal = 0;
230 if (freezing(task) && is_task_frozen_enough(task))
237 if (nfrozen == ntotal)
240 BUG_ON(nfrozen != ntotal);
246 static int freezer_read(
struct cgroup *cgroup,
struct cftype *cft,
249 struct freezer *freezer;
255 freezer = cgroup_freezer(cgroup);
256 spin_lock_irq(&freezer->
lock);
257 state = freezer->
state;
261 update_if_frozen(cgroup, freezer);
262 state = freezer->
state;
264 spin_unlock_irq(&freezer->
lock);
267 seq_puts(m, freezer_state_strs[state]);
272 static int try_to_freeze_cgroup(
struct cgroup *cgroup,
struct freezer *freezer)
274 struct cgroup_iter it;
276 unsigned int num_cant_freeze_now = 0;
282 if (is_task_frozen_enough(task))
284 if (!freezing(task) && !freezer_should_skip(task))
285 num_cant_freeze_now++;
289 return num_cant_freeze_now ? -EBUSY : 0;
292 static void unfreeze_cgroup(
struct cgroup *cgroup,
struct freezer *freezer)
294 struct cgroup_iter it;
303 static int freezer_change_state(
struct cgroup *cgroup,
306 struct freezer *freezer;
309 freezer = cgroup_freezer(cgroup);
311 spin_lock_irq(&freezer->
lock);
313 update_if_frozen(cgroup, freezer);
315 switch (goal_state) {
320 unfreeze_cgroup(cgroup, freezer);
326 retval = try_to_freeze_cgroup(cgroup, freezer);
332 spin_unlock_irq(&freezer->
lock);
337 static int freezer_write(
struct cgroup *cgroup,
353 retval = freezer_change_state(cgroup, goal_state);
358 static struct cftype
files[] = {
361 .flags = CFTYPE_NOT_ON_ROOT,
362 .read_seq_string = freezer_read,
363 .write_string = freezer_write,
370 .create = freezer_create,
371 .destroy = freezer_destroy,
372 .subsys_id = freezer_subsys_id,
373 .can_attach = freezer_can_attach,
374 .fork = freezer_fork,
375 .base_cftypes =
files,
383 .broken_hierarchy =
true,