1 // SPDX-License-Identifier: GPL-2.0-only << 2 /* 1 /* 3 * kernel/freezer.c - Function to freeze a pro 2 * kernel/freezer.c - Function to freeze a process 4 * 3 * 5 * Originally from kernel/power/process.c 4 * Originally from kernel/power/process.c 6 */ 5 */ 7 6 8 #include <linux/interrupt.h> 7 #include <linux/interrupt.h> 9 #include <linux/suspend.h> 8 #include <linux/suspend.h> 10 #include <linux/export.h> !! 9 #include <linux/module.h> 11 #include <linux/syscalls.h> 10 #include <linux/syscalls.h> 12 #include <linux/freezer.h> 11 #include <linux/freezer.h> 13 #include <linux/kthread.h> << 14 << 15 /* total number of freezing conditions in effe << 16 DEFINE_STATIC_KEY_FALSE(freezer_active); << 17 EXPORT_SYMBOL(freezer_active); << 18 12 19 /* 13 /* 20 * indicate whether PM freezing is in effect, !! 14 * freezing is complete, mark current process as frozen 21 * system_transition_mutex << 22 */ 15 */ 23 bool pm_freezing; !! 16 static inline void frozen_process(void) 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 << 31 * @p: task to be tested << 32 * << 33 * This function is called by freezing() if fr << 34 * and tests whether @p needs to enter and sta << 35 * called under any context. The freezers are << 36 * target tasks see the updated state. << 37 */ << 38 bool freezing_slow_path(struct task_struct *p) << 39 { << 40 if (p->flags & (PF_NOFREEZE | PF_SUSPE << 41 return false; << 42 << 43 if (test_tsk_thread_flag(p, TIF_MEMDIE << 44 return false; << 45 << 46 if (pm_nosig_freezing || cgroup_freezi << 47 return true; << 48 << 49 if (pm_freezing && !(p->flags & PF_KTH << 50 return true; << 51 << 52 return false; << 53 } << 54 EXPORT_SYMBOL(freezing_slow_path); << 55 << 56 bool frozen(struct task_struct *p) << 57 { 17 { 58 return READ_ONCE(p->__state) & TASK_FR !! 18 if (!unlikely(current->flags & PF_NOFREEZE)) { >> 19 current->flags |= PF_FROZEN; >> 20 wmb(); >> 21 } >> 22 clear_freeze_flag(current); 59 } 23 } 60 24 61 /* Refrigerator is place where frozen processe 25 /* Refrigerator is place where frozen processes are stored :-). */ 62 bool __refrigerator(bool check_kthr_stop) !! 26 void refrigerator(void) 63 { 27 { 64 unsigned int state = get_current_state !! 28 /* Hmm, should we be allowed to suspend when there are realtime 65 bool was_frozen = false; !! 29 processes around? */ 66 !! 30 long save; >> 31 >> 32 task_lock(current); >> 33 if (freezing(current)) { >> 34 frozen_process(); >> 35 task_unlock(current); >> 36 } else { >> 37 task_unlock(current); >> 38 return; >> 39 } >> 40 save = current->state; 67 pr_debug("%s entered refrigerator\n", 41 pr_debug("%s entered refrigerator\n", current->comm); 68 42 69 WARN_ON_ONCE(state && !(state & TASK_N !! 43 spin_lock_irq(¤t->sighand->siglock); >> 44 recalc_sigpending(); /* We sent fake signal, clean it up */ >> 45 spin_unlock_irq(¤t->sighand->siglock); 70 46 71 for (;;) { !! 47 /* prevent accounting of that task to load */ 72 bool freeze; !! 48 current->flags |= PF_FREEZING; 73 << 74 raw_spin_lock_irq(¤t->pi << 75 WRITE_ONCE(current->__state, T << 76 /* unstale saved_state so that << 77 current->saved_state = TASK_RU << 78 raw_spin_unlock_irq(¤t-> << 79 << 80 spin_lock_irq(&freezer_lock); << 81 freeze = freezing(current) && << 82 spin_unlock_irq(&freezer_lock) << 83 49 84 if (!freeze) !! 50 for (;;) { >> 51 set_current_state(TASK_UNINTERRUPTIBLE); >> 52 if (!frozen(current)) 85 break; 53 break; 86 << 87 was_frozen = true; << 88 schedule(); 54 schedule(); 89 } 55 } 90 __set_current_state(TASK_RUNNING); << 91 56 92 pr_debug("%s left refrigerator\n", cur !! 57 /* Remove the accounting blocker */ >> 58 current->flags &= ~PF_FREEZING; 93 59 94 return was_frozen; !! 60 pr_debug("%s left refrigerator\n", current->comm); >> 61 __set_current_state(save); 95 } 62 } 96 EXPORT_SYMBOL(__refrigerator); !! 63 EXPORT_SYMBOL(refrigerator); 97 64 98 static void fake_signal_wake_up(struct task_st 65 static void fake_signal_wake_up(struct task_struct *p) 99 { 66 { 100 unsigned long flags; 67 unsigned long flags; 101 68 102 if (lock_task_sighand(p, &flags)) { !! 69 spin_lock_irqsave(&p->sighand->siglock, flags); 103 signal_wake_up(p, 0); !! 70 signal_wake_up(p, 0); 104 unlock_task_sighand(p, &flags) !! 71 spin_unlock_irqrestore(&p->sighand->siglock, flags); 105 } << 106 } << 107 << 108 static int __set_task_frozen(struct task_struc << 109 { << 110 unsigned int state = READ_ONCE(p->__st << 111 << 112 /* << 113 * Allow freezing the sched_delayed ta << 114 * ttwu() fixes them up, so it is safe << 115 * of waiting for them to get fully de << 116 */ << 117 if (task_is_runnable(p)) << 118 return 0; << 119 << 120 if (p != current && task_curr(p)) << 121 return 0; << 122 << 123 if (!(state & (TASK_FREEZABLE | __TASK << 124 return 0; << 125 << 126 /* << 127 * Only TASK_NORMAL can be augmented w << 128 * can suffer spurious wakeups. << 129 */ << 130 if (state & TASK_FREEZABLE) << 131 WARN_ON_ONCE(!(state & TASK_NO << 132 << 133 #ifdef CONFIG_LOCKDEP << 134 /* << 135 * It's dangerous to freeze with locks << 136 */ << 137 if (!(state & __TASK_FREEZABLE_UNSAFE) << 138 WARN_ON_ONCE(debug_locks && p- << 139 #endif << 140 << 141 p->saved_state = p->__state; << 142 WRITE_ONCE(p->__state, TASK_FROZEN); << 143 return TASK_FROZEN; << 144 } << 145 << 146 static bool __freeze_task(struct task_struct * << 147 { << 148 /* TASK_FREEZABLE|TASK_STOPPED|TASK_TR << 149 return task_call_func(p, __set_task_fr << 150 } 72 } 151 73 152 /** 74 /** 153 * freeze_task - send a freeze request to give !! 75 * freeze_task - send a freeze request to given task 154 * @p: task to send the request to !! 76 * @p: task to send the request to >> 77 * @sig_only: if set, the request will only be sent if the task has the >> 78 * PF_FREEZER_NOSIG flag unset >> 79 * Return value: 'false', if @sig_only is set and the task has >> 80 * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise 155 * 81 * 156 * If @p is freezing, the freeze request is se !! 82 * The freeze request is sent by setting the tasks's TIF_FREEZE flag and 157 * signal (if it's not a kernel thread) or wak !! 83 * either sending a fake signal to it or waking it up, depending on whether 158 * thread). !! 84 * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task 159 * !! 85 * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its 160 * RETURNS: !! 86 * TIF_FREEZE flag will not be set. 161 * %false, if @p is not freezing or already fr << 162 */ 87 */ 163 bool freeze_task(struct task_struct *p) !! 88 bool freeze_task(struct task_struct *p, bool sig_only) 164 { 89 { 165 unsigned long flags; !! 90 /* >> 91 * We first check if the task is freezing and next if it has already >> 92 * been frozen to avoid the race with frozen_process() which first marks >> 93 * the task as frozen and next clears its TIF_FREEZE. >> 94 */ >> 95 if (!freezing(p)) { >> 96 rmb(); >> 97 if (frozen(p)) >> 98 return false; >> 99 >> 100 if (!sig_only || should_send_signal(p)) >> 101 set_freeze_flag(p); >> 102 else >> 103 return false; >> 104 } 166 105 167 spin_lock_irqsave(&freezer_lock, flags !! 106 if (should_send_signal(p)) { 168 if (!freezing(p) || frozen(p) || __fre !! 107 if (!signal_pending(p)) 169 spin_unlock_irqrestore(&freeze !! 108 fake_signal_wake_up(p); >> 109 } else if (sig_only) { 170 return false; 110 return false; >> 111 } else { >> 112 wake_up_state(p, TASK_INTERRUPTIBLE); 171 } 113 } 172 114 173 if (!(p->flags & PF_KTHREAD)) << 174 fake_signal_wake_up(p); << 175 else << 176 wake_up_state(p, TASK_NORMAL); << 177 << 178 spin_unlock_irqrestore(&freezer_lock, << 179 return true; 115 return true; 180 } 116 } 181 117 182 /* !! 118 void cancel_freezing(struct task_struct *p) 183 * Restore the saved_state before the task ent << 184 * in the __refrigerator(), saved_state == TAS << 185 * here. For tasks which were TASK_NORMAL | TA << 186 * is restored unless they got an expected wak << 187 * Returns 1 if the task state was restored. << 188 */ << 189 static int __restore_freezer_state(struct task << 190 { 119 { 191 unsigned int state = p->saved_state; !! 120 unsigned long flags; 192 121 193 if (state != TASK_RUNNING) { !! 122 if (freezing(p)) { 194 WRITE_ONCE(p->__state, state); !! 123 pr_debug(" clean up: %s\n", p->comm); 195 p->saved_state = TASK_RUNNING; !! 124 clear_freeze_flag(p); 196 return 1; !! 125 spin_lock_irqsave(&p->sighand->siglock, flags); >> 126 recalc_sigpending_and_wake(p); >> 127 spin_unlock_irqrestore(&p->sighand->siglock, flags); 197 } 128 } 198 << 199 return 0; << 200 } 129 } 201 130 202 void __thaw_task(struct task_struct *p) !! 131 static int __thaw_process(struct task_struct *p) 203 { 132 { 204 unsigned long flags; !! 133 if (frozen(p)) { 205 !! 134 p->flags &= ~PF_FROZEN; 206 spin_lock_irqsave(&freezer_lock, flags !! 135 return 1; 207 if (WARN_ON_ONCE(freezing(p))) !! 136 } 208 goto unlock; !! 137 clear_freeze_flag(p); 209 !! 138 return 0; 210 if (!frozen(p) || task_call_func(p, __ << 211 goto unlock; << 212 << 213 wake_up_state(p, TASK_FROZEN); << 214 unlock: << 215 spin_unlock_irqrestore(&freezer_lock, << 216 } 139 } 217 140 218 /** !! 141 /* 219 * set_freezable - make %current freezable !! 142 * Wake up a frozen process 220 * 143 * 221 * Mark %current freezable and enter refrigera !! 144 * task_lock() is needed to prevent the race with refrigerator() which may 222 */ !! 145 * occur if the freezing of tasks fails. Namely, without the lock, if the 223 bool set_freezable(void) !! 146 * freezing of tasks failed, thaw_tasks() might have run before a task in 224 { !! 147 * refrigerator() could call frozen_process(), in which case the task would be 225 might_sleep(); !! 148 * frozen and no one would thaw it. 226 !! 149 */ 227 /* !! 150 int thaw_process(struct task_struct *p) 228 * Modify flags while holding freezer_ !! 151 { 229 * freezer notices that we aren't froz !! 152 task_lock(p); 230 * condition is visible to try_to_free !! 153 if (__thaw_process(p) == 1) { 231 */ !! 154 task_unlock(p); 232 spin_lock_irq(&freezer_lock); !! 155 wake_up_process(p); 233 current->flags &= ~PF_NOFREEZE; !! 156 return 1; 234 spin_unlock_irq(&freezer_lock); !! 157 } 235 !! 158 task_unlock(p); 236 return try_to_freeze(); !! 159 return 0; 237 } 160 } 238 EXPORT_SYMBOL(set_freezable); !! 161 EXPORT_SYMBOL(thaw_process); 239 162
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.