1 /* 2 * kernel/freezer.c - Function to freeze a process 3 * 4 * Originally from kernel/power/process.c 5 */ 6 7 #include <linux/interrupt.h> 8 #include <linux/suspend.h> 9 #include <linux/module.h> 10 #include <linux/syscalls.h> 11 #include <linux/freezer.h> 12 13 /* 14 * freezing is complete, mark current process as frozen 15 */ 16 static inline void frozen_process(void) 17 { 18 if (!unlikely(current->flags & PF_NOFREEZE)) { 19 current->flags |= PF_FROZEN; 20 wmb(); 21 } 22 clear_freeze_flag(current); 23 } 24 25 /* Refrigerator is place where frozen processes are stored :-). */ 26 void refrigerator(void) 27 { 28 /* Hmm, should we be allowed to suspend when there are realtime 29 processes around? */ 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; 41 pr_debug("%s entered refrigerator\n", current->comm); 42 43 spin_lock_irq(¤t->sighand->siglock); 44 recalc_sigpending(); /* We sent fake signal, clean it up */ 45 spin_unlock_irq(¤t->sighand->siglock); 46 47 /* prevent accounting of that task to load */ 48 current->flags |= PF_FREEZING; 49 50 for (;;) { 51 set_current_state(TASK_UNINTERRUPTIBLE); 52 if (!frozen(current)) 53 break; 54 schedule(); 55 } 56 57 /* Remove the accounting blocker */ 58 current->flags &= ~PF_FREEZING; 59 60 pr_debug("%s left refrigerator\n", current->comm); 61 __set_current_state(save); 62 } 63 EXPORT_SYMBOL(refrigerator); 64 65 static void fake_signal_wake_up(struct task_struct *p) 66 { 67 unsigned long flags; 68 69 spin_lock_irqsave(&p->sighand->siglock, flags); 70 signal_wake_up(p, 0); 71 spin_unlock_irqrestore(&p->sighand->siglock, flags); 72 } 73 74 /** 75 * freeze_task - send a freeze request to given task 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 81 * 82 * The freeze request is sent by setting the tasks's TIF_FREEZE flag and 83 * either sending a fake signal to it or waking it up, depending on whether 84 * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task 85 * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its 86 * TIF_FREEZE flag will not be set. 87 */ 88 bool freeze_task(struct task_struct *p, bool sig_only) 89 { 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 } 105 106 if (should_send_signal(p)) { 107 fake_signal_wake_up(p); 108 /* 109 * fake_signal_wake_up() goes through p's scheduler 110 * lock and guarantees that TASK_STOPPED/TRACED -> 111 * TASK_RUNNING transition can't race with task state 112 * testing in try_to_freeze_tasks(). 113 */ 114 } else if (sig_only) { 115 return false; 116 } else { 117 wake_up_state(p, TASK_INTERRUPTIBLE); 118 } 119 120 return true; 121 } 122 123 void cancel_freezing(struct task_struct *p) 124 { 125 unsigned long flags; 126 127 if (freezing(p)) { 128 pr_debug(" clean up: %s\n", p->comm); 129 clear_freeze_flag(p); 130 spin_lock_irqsave(&p->sighand->siglock, flags); 131 recalc_sigpending_and_wake(p); 132 spin_unlock_irqrestore(&p->sighand->siglock, flags); 133 } 134 } 135 136 static int __thaw_process(struct task_struct *p) 137 { 138 if (frozen(p)) { 139 p->flags &= ~PF_FROZEN; 140 return 1; 141 } 142 clear_freeze_flag(p); 143 return 0; 144 } 145 146 /* 147 * Wake up a frozen process 148 * 149 * task_lock() is needed to prevent the race with refrigerator() which may 150 * occur if the freezing of tasks fails. Namely, without the lock, if the 151 * freezing of tasks failed, thaw_tasks() might have run before a task in 152 * refrigerator() could call frozen_process(), in which case the task would be 153 * frozen and no one would thaw it. 154 */ 155 int thaw_process(struct task_struct *p) 156 { 157 task_lock(p); 158 if (__thaw_process(p) == 1) { 159 task_unlock(p); 160 wake_up_process(p); 161 return 1; 162 } 163 task_unlock(p); 164 return 0; 165 } 166 EXPORT_SYMBOL(thaw_process); 167