Skip to content

Commit 22b4e11

Browse files
committed
cgroup_freezer: prepare for removal of TIF_FREEZE
TIF_FREEZE will be removed soon and freezing() will directly test whether any freezing condition is in effect. Make the following changes in preparation. * Rename cgroup_freezing_or_frozen() to cgroup_freezing() and make it return bool. * Make cgroup_freezing() access task_freezer() under rcu read lock instead of task_lock(). This makes the state dereferencing racy against task moving to another cgroup; however, it was already racy without this change as ->state dereference wasn't synchronized. This will be later dealt with using attach hooks. * freezer->state is now set before trying to push tasks into the target state. -v2: Oleg pointed out that freeze_change_state() was setting freeze->state incorrectly to CGROUP_FROZEN instead of CGROUP_FREEZING. Fixed. -v3: Matt pointed out that setting CGROUP_FROZEN used to always invoke try_to_freeze_cgroup() regardless of the current state. Patch updated such that the actual freeze/thaw operations are always performed on invocation. This shouldn't make any difference unless something is broken. Signed-off-by: Tejun Heo <[email protected]> Acked-by: Paul Menage <[email protected]> Cc: Li Zefan <[email protected]> Cc: Oleg Nesterov <[email protected]>
1 parent 03afed8 commit 22b4e11

File tree

3 files changed

+17
-31
lines changed

3 files changed

+17
-31
lines changed

include/linux/freezer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ static inline bool try_to_freeze(void)
6363
extern bool freeze_task(struct task_struct *p, bool sig_only);
6464

6565
#ifdef CONFIG_CGROUP_FREEZER
66-
extern int cgroup_freezing_or_frozen(struct task_struct *task);
66+
extern bool cgroup_freezing(struct task_struct *task);
6767
#else /* !CONFIG_CGROUP_FREEZER */
68-
static inline int cgroup_freezing_or_frozen(struct task_struct *task)
68+
static inline bool cgroup_freezing(struct task_struct *task)
6969
{
70-
return 0;
70+
return false;
7171
}
7272
#endif /* !CONFIG_CGROUP_FREEZER */
7373

kernel/cgroup_freezer.c

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,17 @@ static inline struct freezer *task_freezer(struct task_struct *task)
4848
struct freezer, css);
4949
}
5050

51-
static inline int __cgroup_freezing_or_frozen(struct task_struct *task)
51+
bool cgroup_freezing(struct task_struct *task)
5252
{
53-
enum freezer_state state = task_freezer(task)->state;
54-
return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN);
55-
}
53+
enum freezer_state state;
54+
bool ret;
5655

57-
int cgroup_freezing_or_frozen(struct task_struct *task)
58-
{
59-
int result;
60-
task_lock(task);
61-
result = __cgroup_freezing_or_frozen(task);
62-
task_unlock(task);
63-
return result;
56+
rcu_read_lock();
57+
state = task_freezer(task)->state;
58+
ret = state == CGROUP_FREEZING || state == CGROUP_FROZEN;
59+
rcu_read_unlock();
60+
61+
return ret;
6462
}
6563

6664
/*
@@ -102,9 +100,6 @@ struct cgroup_subsys freezer_subsys;
102100
* freezer_can_attach():
103101
* cgroup_mutex (held by caller of can_attach)
104102
*
105-
* cgroup_freezing_or_frozen():
106-
* task->alloc_lock (to get task's cgroup)
107-
*
108103
* freezer_fork() (preserving fork() performance means can't take cgroup_mutex):
109104
* freezer->lock
110105
* sighand->siglock (if the cgroup is freezing)
@@ -177,13 +172,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss,
177172

178173
static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
179174
{
180-
rcu_read_lock();
181-
if (__cgroup_freezing_or_frozen(tsk)) {
182-
rcu_read_unlock();
183-
return -EBUSY;
184-
}
185-
rcu_read_unlock();
186-
return 0;
175+
return cgroup_freezing(tsk) ? -EBUSY : 0;
187176
}
188177

189178
static 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)
279268
struct task_struct *task;
280269
unsigned int num_cant_freeze_now = 0;
281270

282-
freezer->state = CGROUP_FREEZING;
283271
cgroup_iter_start(cgroup, &it);
284272
while ((task = cgroup_iter_next(cgroup, &it))) {
285273
if (!freeze_task(task, true))
@@ -303,8 +291,6 @@ static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
303291
while ((task = cgroup_iter_next(cgroup, &it)))
304292
__thaw_task(task);
305293
cgroup_iter_end(cgroup, &it);
306-
307-
freezer->state = CGROUP_THAWED;
308294
}
309295

310296
static int freezer_change_state(struct cgroup *cgroup,
@@ -318,20 +304,20 @@ static int freezer_change_state(struct cgroup *cgroup,
318304
spin_lock_irq(&freezer->lock);
319305

320306
update_if_frozen(cgroup, freezer);
321-
if (goal_state == freezer->state)
322-
goto out;
323307

324308
switch (goal_state) {
325309
case CGROUP_THAWED:
310+
freezer->state = CGROUP_THAWED;
326311
unfreeze_cgroup(cgroup, freezer);
327312
break;
328313
case CGROUP_FROZEN:
314+
freezer->state = CGROUP_FREEZING;
329315
retval = try_to_freeze_cgroup(cgroup, freezer);
330316
break;
331317
default:
332318
BUG();
333319
}
334-
out:
320+
335321
spin_unlock_irq(&freezer->lock);
336322

337323
return retval;

kernel/power/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void thaw_processes(void)
170170

171171
read_lock(&tasklist_lock);
172172
do_each_thread(g, p) {
173-
if (cgroup_freezing_or_frozen(p))
173+
if (cgroup_freezing(p))
174174
continue;
175175

176176
__thaw_task(p);

0 commit comments

Comments
 (0)