aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup_freezer.c
diff options
context:
space:
mode:
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++;