| From f43f0c2b296e94d5a3f6690f4799d3a83008a6c0 Mon Sep 17 00:00:00 2001 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Mon, 21 Nov 2011 12:32:24 -0800 |
| Subject: 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> |
| (cherry picked from commit 85f1d476653f52c97ca75466b2494e67c1cbd25d) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| kernel/freezer.c | 3 ++- |
| kernel/power/process.c | 16 +--------------- |
| 2 files changed, 3 insertions(+), 16 deletions(-) |
| |
| diff --git a/kernel/freezer.c b/kernel/freezer.c |
| index e87f5d9..a26f0d2 100644 |
| --- a/kernel/freezer.c |
| +++ b/kernel/freezer.c |
| @@ -109,7 +109,8 @@ bool freeze_task(struct task_struct *p, bool sig_only) |
| |
| spin_lock_irqsave(&freezer_lock, flags); |
| |
| - if (sig_only && !should_send_signal(p)) |
| + if ((p->flags & PF_NOFREEZE) || |
| + (sig_only && !should_send_signal(p))) |
| goto out_unlock; |
| |
| if (frozen(p)) |
| diff --git a/kernel/power/process.c b/kernel/power/process.c |
| index e6e2739..e59676f 100644 |
| --- a/kernel/power/process.c |
| +++ b/kernel/power/process.c |
| @@ -22,14 +22,6 @@ |
| */ |
| #define TIMEOUT (20 * HZ) |
| |
| -static inline int freezable(struct task_struct * p) |
| -{ |
| - if ((p == current) || |
| - (p->flags & PF_NOFREEZE)) |
| - return 0; |
| - return 1; |
| -} |
| - |
| static int try_to_freeze_tasks(bool sig_only) |
| { |
| struct task_struct *g, *p; |
| @@ -52,10 +44,7 @@ static int try_to_freeze_tasks(bool sig_only) |
| todo = 0; |
| read_lock(&tasklist_lock); |
| do_each_thread(g, p) { |
| - if (frozen(p) || !freezable(p)) |
| - continue; |
| - |
| - if (!freeze_task(p, sig_only)) |
| + if (p == current || !freeze_task(p, sig_only)) |
| continue; |
| |
| /* |
| @@ -181,9 +170,6 @@ void thaw_processes(void) |
| |
| read_lock(&tasklist_lock); |
| do_each_thread(g, p) { |
| - if (!freezable(p)) |
| - continue; |
| - |
| if (cgroup_freezing_or_frozen(p)) |
| continue; |
| |
| -- |
| 1.7.10.1.362.g242cab3 |
| |