0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/interrupt.h>
0009 #include <linux/suspend.h>
0010 #include <linux/export.h>
0011 #include <linux/syscalls.h>
0012 #include <linux/freezer.h>
0013 #include <linux/kthread.h>
0014
0015
0016 atomic_t system_freezing_cnt = ATOMIC_INIT(0);
0017 EXPORT_SYMBOL(system_freezing_cnt);
0018
0019
0020
0021
0022 bool pm_freezing;
0023 bool pm_nosig_freezing;
0024
0025
0026 static DEFINE_SPINLOCK(freezer_lock);
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 bool freezing_slow_path(struct task_struct *p)
0038 {
0039 if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
0040 return false;
0041
0042 if (test_tsk_thread_flag(p, TIF_MEMDIE))
0043 return false;
0044
0045 if (pm_nosig_freezing || cgroup_freezing(p))
0046 return true;
0047
0048 if (pm_freezing && !(p->flags & PF_KTHREAD))
0049 return true;
0050
0051 return false;
0052 }
0053 EXPORT_SYMBOL(freezing_slow_path);
0054
0055
0056 bool __refrigerator(bool check_kthr_stop)
0057 {
0058
0059
0060 bool was_frozen = false;
0061 unsigned int save = get_current_state();
0062
0063 pr_debug("%s entered refrigerator\n", current->comm);
0064
0065 for (;;) {
0066 set_current_state(TASK_UNINTERRUPTIBLE);
0067
0068 spin_lock_irq(&freezer_lock);
0069 current->flags |= PF_FROZEN;
0070 if (!freezing(current) ||
0071 (check_kthr_stop && kthread_should_stop()))
0072 current->flags &= ~PF_FROZEN;
0073 spin_unlock_irq(&freezer_lock);
0074
0075 if (!(current->flags & PF_FROZEN))
0076 break;
0077 was_frozen = true;
0078 schedule();
0079 }
0080
0081 pr_debug("%s left refrigerator\n", current->comm);
0082
0083
0084
0085
0086
0087
0088 set_current_state(save);
0089
0090 return was_frozen;
0091 }
0092 EXPORT_SYMBOL(__refrigerator);
0093
0094 static void fake_signal_wake_up(struct task_struct *p)
0095 {
0096 unsigned long flags;
0097
0098 if (lock_task_sighand(p, &flags)) {
0099 signal_wake_up(p, 0);
0100 unlock_task_sighand(p, &flags);
0101 }
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 bool freeze_task(struct task_struct *p)
0116 {
0117 unsigned long flags;
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 if (freezer_should_skip(p))
0129 return false;
0130
0131 spin_lock_irqsave(&freezer_lock, flags);
0132 if (!freezing(p) || frozen(p)) {
0133 spin_unlock_irqrestore(&freezer_lock, flags);
0134 return false;
0135 }
0136
0137 if (!(p->flags & PF_KTHREAD))
0138 fake_signal_wake_up(p);
0139 else
0140 wake_up_state(p, TASK_INTERRUPTIBLE);
0141
0142 spin_unlock_irqrestore(&freezer_lock, flags);
0143 return true;
0144 }
0145
0146 void __thaw_task(struct task_struct *p)
0147 {
0148 unsigned long flags;
0149
0150 spin_lock_irqsave(&freezer_lock, flags);
0151 if (frozen(p))
0152 wake_up_process(p);
0153 spin_unlock_irqrestore(&freezer_lock, flags);
0154 }
0155
0156
0157
0158
0159
0160
0161 bool set_freezable(void)
0162 {
0163 might_sleep();
0164
0165
0166
0167
0168
0169
0170 spin_lock_irq(&freezer_lock);
0171 current->flags &= ~PF_NOFREEZE;
0172 spin_unlock_irq(&freezer_lock);
0173
0174 return try_to_freeze();
0175 }
0176 EXPORT_SYMBOL(set_freezable);