aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/freezer.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-11-21 15:32:23 -0500
committerTejun Heo <tj@kernel.org>2011-11-21 15:32:23 -0500
commit8a32c441c1609f80e55df75422324a1151208f40 (patch)
tree73884b06cc2db3ea155af9a88815bb5105a4473e /kernel/freezer.c
parenta0acae0e886d44bd5ce6d2f173c1ace0fcf0d9f6 (diff)
freezer: implement and use kthread_freezable_should_stop()
Writeback and thinkpad_acpi have been using thaw_process() to prevent deadlock between the freezer and kthread_stop(); unfortunately, this is inherently racy - nothing prevents freezing from happening between thaw_process() and kthread_stop(). This patch implements kthread_freezable_should_stop() which enters refrigerator if necessary but is guaranteed to return if kthread_stop() is invoked. Both thaw_process() users are converted to use the new function. Note that this deadlock condition exists for many of freezable kthreads. They need to be converted to use the new should_stop or freezable workqueue. Tested with synthetic test case. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> Cc: Jens Axboe <axboe@kernel.dk> Cc: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'kernel/freezer.c')
-rw-r--r--kernel/freezer.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/freezer.c b/kernel/freezer.c
index 732f14f5944f..b83c30e9483a 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -9,6 +9,7 @@
9#include <linux/export.h> 9#include <linux/export.h>
10#include <linux/syscalls.h> 10#include <linux/syscalls.h>
11#include <linux/freezer.h> 11#include <linux/freezer.h>
12#include <linux/kthread.h>
12 13
13/* 14/*
14 * freezing is complete, mark current process as frozen 15 * freezing is complete, mark current process as frozen
@@ -23,7 +24,7 @@ static inline void frozen_process(void)
23} 24}
24 25
25/* Refrigerator is place where frozen processes are stored :-). */ 26/* Refrigerator is place where frozen processes are stored :-). */
26bool __refrigerator(void) 27bool __refrigerator(bool check_kthr_stop)
27{ 28{
28 /* Hmm, should we be allowed to suspend when there are realtime 29 /* Hmm, should we be allowed to suspend when there are realtime
29 processes around? */ 30 processes around? */
@@ -50,7 +51,8 @@ bool __refrigerator(void)
50 51
51 for (;;) { 52 for (;;) {
52 set_current_state(TASK_UNINTERRUPTIBLE); 53 set_current_state(TASK_UNINTERRUPTIBLE);
53 if (!frozen(current)) 54 if (!frozen(current) ||
55 (check_kthr_stop && kthread_should_stop()))
54 break; 56 break;
55 was_frozen = true; 57 was_frozen = true;
56 schedule(); 58 schedule();