diff options
author | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:24 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:24 -0500 |
commit | 85f1d476653f52c97ca75466b2494e67c1cbd25d (patch) | |
tree | a1839143272cc4e6593e5d4c97e8a3c39aed08ff /kernel | |
parent | 6907483b4e803a20f0b48cc9afa3817420ce61c5 (diff) |
freezer: test freezable conditions while holding freezer_lock
try_to_freeze_tasks() and thaw_processes() use freezable() and
frozen() as preliminary tests before initiating operations on a task.
These are done without any synchronization and hinder with
synchronization cleanup without any real performance benefits.
In try_to_freeze_tasks(), open code self test and move PF_NOFREEZE and
frozen() tests inside freezer_lock in freeze_task().
thaw_processes() can simply drop freezable() test as frozen() test in
__thaw_task() is enough.
Note: This used to be a part of larger patch to fix set_freezable()
race. Separated out to satisfy ordering among dependent fixes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/freezer.c | 3 | ||||
-rw-r--r-- | kernel/power/process.c | 16 |
2 files changed, 3 insertions, 16 deletions
diff --git a/kernel/freezer.c b/kernel/freezer.c index a8822be43da0..a257ecd37c48 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c | |||
@@ -109,7 +109,8 @@ bool freeze_task(struct task_struct *p, bool sig_only) | |||
109 | 109 | ||
110 | spin_lock_irqsave(&freezer_lock, flags); | 110 | spin_lock_irqsave(&freezer_lock, flags); |
111 | 111 | ||
112 | if (sig_only && !should_send_signal(p)) | 112 | if ((p->flags & PF_NOFREEZE) || |
113 | (sig_only && !should_send_signal(p))) | ||
113 | goto out_unlock; | 114 | goto out_unlock; |
114 | 115 | ||
115 | if (frozen(p)) | 116 | if (frozen(p)) |
diff --git a/kernel/power/process.c b/kernel/power/process.c index e6e2739190b5..e59676f5811d 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -22,14 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | #define TIMEOUT (20 * HZ) | 23 | #define TIMEOUT (20 * HZ) |
24 | 24 | ||
25 | static inline int freezable(struct task_struct * p) | ||
26 | { | ||
27 | if ((p == current) || | ||
28 | (p->flags & PF_NOFREEZE)) | ||
29 | return 0; | ||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | static int try_to_freeze_tasks(bool sig_only) | 25 | static int try_to_freeze_tasks(bool sig_only) |
34 | { | 26 | { |
35 | struct task_struct *g, *p; | 27 | struct task_struct *g, *p; |
@@ -52,10 +44,7 @@ static int try_to_freeze_tasks(bool sig_only) | |||
52 | todo = 0; | 44 | todo = 0; |
53 | read_lock(&tasklist_lock); | 45 | read_lock(&tasklist_lock); |
54 | do_each_thread(g, p) { | 46 | do_each_thread(g, p) { |
55 | if (frozen(p) || !freezable(p)) | 47 | if (p == current || !freeze_task(p, sig_only)) |
56 | continue; | ||
57 | |||
58 | if (!freeze_task(p, sig_only)) | ||
59 | continue; | 48 | continue; |
60 | 49 | ||
61 | /* | 50 | /* |
@@ -181,9 +170,6 @@ void thaw_processes(void) | |||
181 | 170 | ||
182 | read_lock(&tasklist_lock); | 171 | read_lock(&tasklist_lock); |
183 | do_each_thread(g, p) { | 172 | do_each_thread(g, p) { |
184 | if (!freezable(p)) | ||
185 | continue; | ||
186 | |||
187 | if (cgroup_freezing_or_frozen(p)) | 173 | if (cgroup_freezing_or_frozen(p)) |
188 | continue; | 174 | continue; |
189 | 175 | ||