Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only 2 : /* 3 : * kernel/freezer.c - Function to freeze a process 4 : * 5 : * Originally from kernel/power/process.c 6 : */ 7 : 8 : #include <linux/interrupt.h> 9 : #include <linux/suspend.h> 10 : #include <linux/export.h> 11 : #include <linux/syscalls.h> 12 : #include <linux/freezer.h> 13 : #include <linux/kthread.h> 14 : 15 : /* total number of freezing conditions in effect */ 16 : DEFINE_STATIC_KEY_FALSE(freezer_active); 17 : EXPORT_SYMBOL(freezer_active); 18 : 19 : /* 20 : * indicate whether PM freezing is in effect, protected by 21 : * system_transition_mutex 22 : */ 23 : bool pm_freezing; 24 : bool pm_nosig_freezing; 25 : 26 : /* protects freezing and frozen transitions */ 27 : static DEFINE_SPINLOCK(freezer_lock); 28 : 29 : /** 30 : * freezing_slow_path - slow path for testing whether a task needs to be frozen 31 : * @p: task to be tested 32 : * 33 : * This function is called by freezing() if freezer_active isn't zero 34 : * and tests whether @p needs to enter and stay in frozen state. Can be 35 : * called under any context. The freezers are responsible for ensuring the 36 : * target tasks see the updated state. 37 : */ 38 0 : bool freezing_slow_path(struct task_struct *p) 39 : { 40 0 : if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK)) 41 : return false; 42 : 43 0 : if (test_tsk_thread_flag(p, TIF_MEMDIE)) 44 : return false; 45 : 46 0 : if (pm_nosig_freezing || cgroup_freezing(p)) 47 : return true; 48 : 49 0 : if (pm_freezing && !(p->flags & PF_KTHREAD)) 50 : return true; 51 : 52 0 : return false; 53 : } 54 : EXPORT_SYMBOL(freezing_slow_path); 55 : 56 0 : bool frozen(struct task_struct *p) 57 : { 58 0 : return READ_ONCE(p->__state) & TASK_FROZEN; 59 : } 60 : 61 : /* Refrigerator is place where frozen processes are stored :-). */ 62 0 : bool __refrigerator(bool check_kthr_stop) 63 : { 64 0 : unsigned int state = get_current_state(); 65 0 : bool was_frozen = false; 66 : 67 : pr_debug("%s entered refrigerator\n", current->comm); 68 : 69 0 : WARN_ON_ONCE(state && !(state & TASK_NORMAL)); 70 : 71 0 : for (;;) { 72 : bool freeze; 73 : 74 0 : set_current_state(TASK_FROZEN); 75 : 76 0 : spin_lock_irq(&freezer_lock); 77 0 : freeze = freezing(current) && !(check_kthr_stop && kthread_should_stop()); 78 0 : spin_unlock_irq(&freezer_lock); 79 : 80 0 : if (!freeze) 81 : break; 82 : 83 0 : was_frozen = true; 84 0 : schedule(); 85 : } 86 0 : __set_current_state(TASK_RUNNING); 87 : 88 : pr_debug("%s left refrigerator\n", current->comm); 89 : 90 0 : return was_frozen; 91 : } 92 : EXPORT_SYMBOL(__refrigerator); 93 : 94 0 : static void fake_signal_wake_up(struct task_struct *p) 95 : { 96 : unsigned long flags; 97 : 98 0 : if (lock_task_sighand(p, &flags)) { 99 0 : signal_wake_up(p, 0); 100 0 : unlock_task_sighand(p, &flags); 101 : } 102 0 : } 103 : 104 0 : static int __set_task_frozen(struct task_struct *p, void *arg) 105 : { 106 0 : unsigned int state = READ_ONCE(p->__state); 107 : 108 0 : if (p->on_rq) 109 : return 0; 110 : 111 0 : if (p != current && task_curr(p)) 112 : return 0; 113 : 114 0 : if (!(state & (TASK_FREEZABLE | __TASK_STOPPED | __TASK_TRACED))) 115 : return 0; 116 : 117 : /* 118 : * Only TASK_NORMAL can be augmented with TASK_FREEZABLE, since they 119 : * can suffer spurious wakeups. 120 : */ 121 0 : if (state & TASK_FREEZABLE) 122 0 : WARN_ON_ONCE(!(state & TASK_NORMAL)); 123 : 124 : #ifdef CONFIG_LOCKDEP 125 : /* 126 : * It's dangerous to freeze with locks held; there be dragons there. 127 : */ 128 : if (!(state & __TASK_FREEZABLE_UNSAFE)) 129 : WARN_ON_ONCE(debug_locks && p->lockdep_depth); 130 : #endif 131 : 132 0 : WRITE_ONCE(p->__state, TASK_FROZEN); 133 0 : return TASK_FROZEN; 134 : } 135 : 136 : static bool __freeze_task(struct task_struct *p) 137 : { 138 : /* TASK_FREEZABLE|TASK_STOPPED|TASK_TRACED -> TASK_FROZEN */ 139 0 : return task_call_func(p, __set_task_frozen, NULL); 140 : } 141 : 142 : /** 143 : * freeze_task - send a freeze request to given task 144 : * @p: task to send the request to 145 : * 146 : * If @p is freezing, the freeze request is sent either by sending a fake 147 : * signal (if it's not a kernel thread) or waking it up (if it's a kernel 148 : * thread). 149 : * 150 : * RETURNS: 151 : * %false, if @p is not freezing or already frozen; %true, otherwise 152 : */ 153 0 : bool freeze_task(struct task_struct *p) 154 : { 155 : unsigned long flags; 156 : 157 0 : spin_lock_irqsave(&freezer_lock, flags); 158 0 : if (!freezing(p) || frozen(p) || __freeze_task(p)) { 159 0 : spin_unlock_irqrestore(&freezer_lock, flags); 160 0 : return false; 161 : } 162 : 163 0 : if (!(p->flags & PF_KTHREAD)) 164 0 : fake_signal_wake_up(p); 165 : else 166 0 : wake_up_state(p, TASK_NORMAL); 167 : 168 0 : spin_unlock_irqrestore(&freezer_lock, flags); 169 0 : return true; 170 : } 171 : 172 : /* 173 : * The special task states (TASK_STOPPED, TASK_TRACED) keep their canonical 174 : * state in p->jobctl. If either of them got a wakeup that was missed because 175 : * TASK_FROZEN, then their canonical state reflects that and the below will 176 : * refuse to restore the special state and instead issue the wakeup. 177 : */ 178 0 : static int __set_task_special(struct task_struct *p, void *arg) 179 : { 180 0 : unsigned int state = 0; 181 : 182 0 : if (p->jobctl & JOBCTL_TRACED) 183 : state = TASK_TRACED; 184 : 185 0 : else if (p->jobctl & JOBCTL_STOPPED) 186 0 : state = TASK_STOPPED; 187 : 188 0 : if (state) 189 0 : WRITE_ONCE(p->__state, state); 190 : 191 0 : return state; 192 : } 193 : 194 0 : void __thaw_task(struct task_struct *p) 195 : { 196 : unsigned long flags, flags2; 197 : 198 0 : spin_lock_irqsave(&freezer_lock, flags); 199 0 : if (WARN_ON_ONCE(freezing(p))) 200 : goto unlock; 201 : 202 0 : if (lock_task_sighand(p, &flags2)) { 203 : /* TASK_FROZEN -> TASK_{STOPPED,TRACED} */ 204 0 : bool ret = task_call_func(p, __set_task_special, NULL); 205 0 : unlock_task_sighand(p, &flags2); 206 0 : if (ret) 207 : goto unlock; 208 : } 209 : 210 0 : wake_up_state(p, TASK_FROZEN); 211 : unlock: 212 0 : spin_unlock_irqrestore(&freezer_lock, flags); 213 0 : } 214 : 215 : /** 216 : * set_freezable - make %current freezable 217 : * 218 : * Mark %current freezable and enter refrigerator if necessary. 219 : */ 220 3 : bool set_freezable(void) 221 : { 222 : might_sleep(); 223 : 224 : /* 225 : * Modify flags while holding freezer_lock. This ensures the 226 : * freezer notices that we aren't frozen yet or the freezing 227 : * condition is visible to try_to_freeze() below. 228 : */ 229 3 : spin_lock_irq(&freezer_lock); 230 3 : current->flags &= ~PF_NOFREEZE; 231 3 : spin_unlock_irq(&freezer_lock); 232 : 233 3 : return try_to_freeze(); 234 : } 235 : EXPORT_SYMBOL(set_freezable);