aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/freezer.h6
-rw-r--r--kernel/cgroup_freezer.c40
-rw-r--r--kernel/power/process.c2
3 files changed, 17 insertions, 31 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 93f411a52872..b2b4abc5a739 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -63,11 +63,11 @@ static inline bool try_to_freeze(void)
63extern bool freeze_task(struct task_struct *p, bool sig_only); 63extern bool freeze_task(struct task_struct *p, bool sig_only);
64 64
65#ifdef CONFIG_CGROUP_FREEZER 65#ifdef CONFIG_CGROUP_FREEZER
66extern int cgroup_freezing_or_frozen(struct task_struct *task); 66extern bool cgroup_freezing(struct task_struct *task);
67#else /* !CONFIG_CGROUP_FREEZER */ 67#else /* !CONFIG_CGROUP_FREEZER */
68static inline int cgroup_freezing_or_frozen(struct task_struct *task) 68static inline bool cgroup_freezing(struct task_struct *task)
69{ 69{
70 return 0; 70 return false;
71} 71}
72#endif /* !CONFIG_CGROUP_FREEZER */ 72#endif /* !CONFIG_CGROUP_FREEZER */
73 73
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index cd27b0825560..e6a1b8d1b8bc 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -48,19 +48,17 @@ static inline struct freezer *task_freezer(struct task_struct *task)
48 struct freezer, css); 48 struct freezer, css);
49} 49}
50 50
51static inline int __cgroup_freezing_or_frozen(struct task_struct *task) 51bool cgroup_freezing(struct task_struct *task)
52{ 52{
53 enum freezer_state state = task_freezer(task)->state; 53 enum freezer_state state;
54 return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); 54 bool ret;
55}
56 55
57int cgroup_freezing_or_frozen(struct task_struct *task) 56 rcu_read_lock();
58{ 57 state = task_freezer(task)->state;
59 int result; 58 ret = state == CGROUP_FREEZING || state == CGROUP_FROZEN;
60 task_lock(task); 59 rcu_read_unlock();
61 result = __cgroup_freezing_or_frozen(task); 60
62 task_unlock(task); 61 return ret;
63 return result;
64} 62}
65 63
66/* 64/*
@@ -102,9 +100,6 @@ struct cgroup_subsys freezer_subsys;
102 * freezer_can_attach(): 100 * freezer_can_attach():
103 * cgroup_mutex (held by caller of can_attach) 101 * cgroup_mutex (held by caller of can_attach)
104 * 102 *
105 * cgroup_freezing_or_frozen():
106 * task->alloc_lock (to get task's cgroup)
107 *
108 * freezer_fork() (preserving fork() performance means can't take cgroup_mutex): 103 * freezer_fork() (preserving fork() performance means can't take cgroup_mutex):
109 * freezer->lock 104 * freezer->lock
110 * sighand->siglock (if the cgroup is freezing) 105 * sighand->siglock (if the cgroup is freezing)
@@ -177,13 +172,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss,
177 172
178static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) 173static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
179{ 174{
180 rcu_read_lock(); 175 return cgroup_freezing(tsk) ? -EBUSY : 0;
181 if (__cgroup_freezing_or_frozen(tsk)) {
182 rcu_read_unlock();
183 return -EBUSY;
184 }
185 rcu_read_unlock();
186 return 0;
187} 176}
188 177
189static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) 178static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
@@ -279,7 +268,6 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
279 struct task_struct *task; 268 struct task_struct *task;
280 unsigned int num_cant_freeze_now = 0; 269 unsigned int num_cant_freeze_now = 0;
281 270
282 freezer->state = CGROUP_FREEZING;
283 cgroup_iter_start(cgroup, &it); 271 cgroup_iter_start(cgroup, &it);
284 while ((task = cgroup_iter_next(cgroup, &it))) { 272 while ((task = cgroup_iter_next(cgroup, &it))) {
285 if (!freeze_task(task, true)) 273 if (!freeze_task(task, true))
@@ -303,8 +291,6 @@ static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
303 while ((task = cgroup_iter_next(cgroup, &it))) 291 while ((task = cgroup_iter_next(cgroup, &it)))
304 __thaw_task(task); 292 __thaw_task(task);
305 cgroup_iter_end(cgroup, &it); 293 cgroup_iter_end(cgroup, &it);
306
307 freezer->state = CGROUP_THAWED;
308} 294}
309 295
310static int freezer_change_state(struct cgroup *cgroup, 296static int freezer_change_state(struct cgroup *cgroup,
@@ -318,20 +304,20 @@ static int freezer_change_state(struct cgroup *cgroup,
318 spin_lock_irq(&freezer->lock); 304 spin_lock_irq(&freezer->lock);
319 305
320 update_if_frozen(cgroup, freezer); 306 update_if_frozen(cgroup, freezer);
321 if (goal_state == freezer->state)
322 goto out;
323 307
324 switch (goal_state) { 308 switch (goal_state) {
325 case CGROUP_THAWED: 309 case CGROUP_THAWED:
310 freezer->state = CGROUP_THAWED;
326 unfreeze_cgroup(cgroup, freezer); 311 unfreeze_cgroup(cgroup, freezer);
327 break; 312 break;
328 case CGROUP_FROZEN: 313 case CGROUP_FROZEN:
314 freezer->state = CGROUP_FREEZING;
329 retval = try_to_freeze_cgroup(cgroup, freezer); 315 retval = try_to_freeze_cgroup(cgroup, freezer);
330 break; 316 break;
331 default: 317 default:
332 BUG(); 318 BUG();
333 } 319 }
334out: 320
335 spin_unlock_irq(&freezer->lock); 321 spin_unlock_irq(&freezer->lock);
336 322
337 return retval; 323 return retval;
diff --git a/kernel/power/process.c b/kernel/power/process.c
index ce643838a00c..9f6f5c755cfa 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -170,7 +170,7 @@ void thaw_processes(void)
170 170
171 read_lock(&tasklist_lock); 171 read_lock(&tasklist_lock);
172 do_each_thread(g, p) { 172 do_each_thread(g, p) {
173 if (cgroup_freezing_or_frozen(p)) 173 if (cgroup_freezing(p))
174 continue; 174 continue;
175 175
176 __thaw_task(p); 176 __thaw_task(p);