diff options
author | Pavel Machek <pavel@ucw.cz> | 2005-09-03 15:57:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 00:06:17 -0700 |
commit | 6161b2ce8116b9a623260ab811e2c035b3fac2e5 (patch) | |
tree | 8cb36b11631c0843fb5a7e600626a2f6a230846b /kernel/power/process.c | |
parent | 99dc7d63e0dcb457580241055b2a39d011309db8 (diff) | |
download | linux-stable-6161b2ce8116b9a623260ab811e2c035b3fac2e5.tar.gz linux-stable-6161b2ce8116b9a623260ab811e2c035b3fac2e5.tar.bz2 linux-stable-6161b2ce8116b9a623260ab811e2c035b3fac2e5.zip |
[PATCH] pm: fix process freezing
If process freezing fails, some processes are frozen, and rest are left in
"were asked to be frozen" state. Thats wrong, we should leave it in some
consistent state.
Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power/process.c')
-rw-r--r-- | kernel/power/process.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c index f7da5bfc914e..28de118f7a0b 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -81,13 +81,33 @@ int freeze_processes(void) } while_each_thread(g, p); read_unlock(&tasklist_lock); yield(); /* Yield is okay here */ - if (time_after(jiffies, start_time + TIMEOUT)) { + if (todo && time_after(jiffies, start_time + TIMEOUT)) { printk( "\n" ); printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo ); - return todo; + break; } } while(todo); + /* This does not unfreeze processes that are already frozen + * (we have slightly ugly calling convention in that respect, + * and caller must call thaw_processes() if something fails), + * but it cleans up leftover PF_FREEZE requests. + */ + if (todo) { + read_lock(&tasklist_lock); + do_each_thread(g, p) + if (freezing(p)) { + pr_debug(" clean up: %s\n", p->comm); + p->flags &= ~PF_FREEZE; + spin_lock_irqsave(&p->sighand->siglock, flags); + recalc_sigpending_tsk(p); + spin_unlock_irqrestore(&p->sighand->siglock, flags); + } + while_each_thread(g, p); + read_unlock(&tasklist_lock); + return todo; + } + printk( "|\n" ); BUG_ON(in_atomic()); return 0; |