#include <linux/interrupt.h>
#include <linux/suspend.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/syscalls.h>
#include <linux/freezer.h>
+#include <linux/kthread.h>
/*
* freezing is complete, mark current process as frozen
}
/* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(void)
+bool __refrigerator(bool check_kthr_stop)
{
/* Hmm, should we be allowed to suspend when there are realtime
processes around? */
+ bool was_frozen = false;
long save;
task_lock(current);
task_unlock(current);
} else {
task_unlock(current);
- return;
+ return was_frozen;
}
save = current->state;
pr_debug("%s entered refrigerator\n", current->comm);
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (!frozen(current))
+ if (!frozen(current) ||
+ (check_kthr_stop && kthread_should_stop()))
break;
+ was_frozen = true;
schedule();
}
current->flags &= ~PF_FREEZING;
pr_debug("%s left refrigerator\n", current->comm);
- __set_current_state(save);
+
+ /*
+ * Restore saved task state before returning. The mb'd version
+ * needs to be used; otherwise, it might silently break
+ * synchronization which depends on ordered task state change.
+ */
+ set_current_state(save);
+
+ return was_frozen;
}
-EXPORT_SYMBOL(refrigerator);
+EXPORT_SYMBOL(__refrigerator);
static void fake_signal_wake_up(struct task_struct *p)
{
unsigned long flags;
spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, 1);
+ signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
}
}
-static int __thaw_process(struct task_struct *p)
-{
- if (frozen(p)) {
- p->flags &= ~PF_FROZEN;
- return 1;
- }
- clear_freeze_flag(p);
- return 0;
-}
-
/*
- * Wake up a frozen process
+ * Wake up a frozen task
*
* task_lock() is needed to prevent the race with refrigerator() which may
* occur if the freezing of tasks fails. Namely, without the lock, if the
* refrigerator() could call frozen_process(), in which case the task would be
* frozen and no one would thaw it.
*/
-int thaw_process(struct task_struct *p)
+void __thaw_task(struct task_struct *p)
{
+ bool was_frozen;
+
task_lock(p);
- if (__thaw_process(p) == 1) {
- task_unlock(p);
- wake_up_process(p);
- return 1;
- }
+ was_frozen = frozen(p);
+ if (was_frozen)
+ p->flags &= ~PF_FROZEN;
+ else
+ clear_freeze_flag(p);
task_unlock(p);
- return 0;
+
+ if (was_frozen)
+ wake_up_process(p);
}
-EXPORT_SYMBOL(thaw_process);