aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/process.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:35:52 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:35:52 -0500
commit181e9bdef37bfcaa41f3ab6c948a2a0d60a268b5 (patch)
tree66e69f83b63e8517a47e0eb0e7ae730d8a9a109b /kernel/power/process.c
parent0a9626575400879d1d5e6bc8768188b938d7c501 (diff)
PM / Hibernate: Fix s2disk regression related to freezing workqueues
Commit 2aede851ddf08666f68ffc17be446420e9d2a056 PM / Hibernate: Freeze kernel threads after preallocating memory introduced a mechanism by which kernel threads were frozen after the preallocation of hibernate image memory to avoid problems with frozen kernel threads not responding to memory freeing requests. However, it overlooked the s2disk code path in which the SNAPSHOT_CREATE_IMAGE ioctl was run directly after SNAPSHOT_FREE, which caused freeze_workqueues_begin() to BUG(), because it saw that worqueues had been already frozen. Although in principle this issue might be addressed by removing the relevant BUG_ON() from freeze_workqueues_begin(), that would reintroduce the very problem that commit 2aede851ddf08666f68ffc17be4 attempted to avoid into that particular code path. For this reason, to fix the issue at hand, introduce thaw_kernel_threads() and make the SNAPSHOT_FREE ioctl execute it. Special thanks to Srivatsa S. Bhat for detailed analysis of the problem. Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Cc: stable@kernel.org
Diffstat (limited to 'kernel/power/process.c')
-rw-r--r--kernel/power/process.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 77274c9ba2f1..eeca00311f39 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -188,3 +188,22 @@ void thaw_processes(void)
188 printk("done.\n"); 188 printk("done.\n");
189} 189}
190 190
191void thaw_kernel_threads(void)
192{
193 struct task_struct *g, *p;
194
195 pm_nosig_freezing = false;
196 printk("Restarting kernel threads ... ");
197
198 thaw_workqueues();
199
200 read_lock(&tasklist_lock);
201 do_each_thread(g, p) {
202 if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
203 __thaw_task(p);
204 } while_each_thread(g, p);
205 read_unlock(&tasklist_lock);
206
207 schedule();
208 printk("done.\n");
209}