diff options
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) | |||
81 | } while_each_thread(g, p); | 81 | } while_each_thread(g, p); |
82 | read_unlock(&tasklist_lock); | 82 | read_unlock(&tasklist_lock); |
83 | yield(); /* Yield is okay here */ | 83 | yield(); /* Yield is okay here */ |
84 | if (time_after(jiffies, start_time + TIMEOUT)) { | 84 | if (todo && time_after(jiffies, start_time + TIMEOUT)) { |
85 | printk( "\n" ); | 85 | printk( "\n" ); |
86 | printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo ); | 86 | printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo ); |
87 | return todo; | 87 | break; |
88 | } | 88 | } |
89 | } while(todo); | 89 | } while(todo); |
90 | 90 | ||
91 | /* This does not unfreeze processes that are already frozen | ||
92 | * (we have slightly ugly calling convention in that respect, | ||
93 | * and caller must call thaw_processes() if something fails), | ||
94 | * but it cleans up leftover PF_FREEZE requests. | ||
95 | */ | ||
96 | if (todo) { | ||
97 | read_lock(&tasklist_lock); | ||
98 | do_each_thread(g, p) | ||
99 | if (freezing(p)) { | ||
100 | pr_debug(" clean up: %s\n", p->comm); | ||
101 | p->flags &= ~PF_FREEZE; | ||
102 | spin_lock_irqsave(&p->sighand->siglock, flags); | ||
103 | recalc_sigpending_tsk(p); | ||
104 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | ||
105 | } | ||
106 | while_each_thread(g, p); | ||
107 | read_unlock(&tasklist_lock); | ||
108 | return todo; | ||
109 | } | ||
110 | |||
91 | printk( "|\n" ); | 111 | printk( "|\n" ); |
92 | BUG_ON(in_atomic()); | 112 | BUG_ON(in_atomic()); |
93 | return 0; | 113 | return 0; |