X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=kernel%2Fpower%2Fprocess.c;fp=kernel%2Fpower%2Fprocess.c;h=28de118f7a0b047c6c507a8adbf2113ce52bb21d;hb=6161b2ce8116b9a623260ab811e2c035b3fac2e5;hp=f7da5bfc914e36904c4585278d1bb50aa8008724;hpb=99dc7d63e0dcb457580241055b2a39d011309db8;p=powerpc.git diff --git a/kernel/power/process.c b/kernel/power/process.c index f7da5bfc91..28de118f7a 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;