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 for (;;) { 48 set_current_state(TASK_UNINTERRUPTIBLE); 49 if (!frozen(current)) 50 break; 51 schedule(); 52 } 53 pr_debug("%s left refrigerator\n", current->comm); 54 __set_current_state(save); 55 } 56 EXPORT_SYMBOL(refrigerator); 57 58 static void fake_signal_wake_up(struct task_struct *p) 59 { 60 unsigned long flags; 61 62 spin_lock_irqsave(&p->sighand->siglock, flags); 63 signal_wake_up(p, 0); 64 spin_unlock_irqrestore(&p->sighand->siglock, flags); 65 } 66 67 /** 68 * freeze_task - send a freeze request to given task 69 * @p: task to send the request to 70 * @sig_only: if set, the request will only be sent if the task has the 71 * PF_FREEZER_NOSIG flag unset 72 * Return value: 'false', if @sig_only is set and the task has 73 * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise 74 * 75 * The freeze request is sent by setting the tasks's TIF_FREEZE flag and 76 * either sending a fake signal to it or waking it up, depending on whether 77 * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task 78 * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its 79 * TIF_FREEZE flag will not be set. 80 */ 81 bool freeze_task(struct task_struct *p, bool sig_only) 82 { 83 /* 84 * We first check if the task is freezing and next if it has already 85 * been frozen to avoid the race with frozen_process() which first marks 86 * the task as frozen and next clears its TIF_FREEZE. 87 */ 88 if (!freezing(p)) { 89 rmb(); 90 if (frozen(p)) 91 return false; 92 93 if (!sig_only || should_send_signal(p)) 94 set_freeze_flag(p); 95 else 96 return false; 97 } 98 99 if (should_send_signal(p)) { 100 if (!signal_pending(p)) 101 fake_signal_wake_up(p); 102 } else if (sig_only) { 103 return false; 104 } else { 105 wake_up_state(p, TASK_INTERRUPTIBLE); 106 } 107 108 return true; 109 } 110 111 void cancel_freezing(struct task_struct *p) 112 { 113 unsigned long flags; 114 115 if (freezing(p)) { 116 pr_debug(" clean up: %s\n", p->comm); 117 clear_freeze_flag(p); 118 spin_lock_irqsave(&p->sighand->siglock, flags); 119 recalc_sigpending_and_wake(p); 120 spin_unlock_irqrestore(&p->sighand->siglock, flags); 121 } 122 } 123 124 static int __thaw_process(struct task_struct *p) 125 { 126 if (frozen(p)) { 127 p->flags &= ~PF_FROZEN; 128 return 1; 129 } 130 clear_freeze_flag(p); 131 return 0; 132 } 133 134 /* 135 * Wake up a frozen process 136 * 137 * task_lock() is needed to prevent the race with refrigerator() which may 138 * occur if the freezing of tasks fails. Namely, without the lock, if the 139 * freezing of tasks failed, thaw_tasks() might have run before a task in 140 * refrigerator() could call frozen_process(), in which case the task would be 141 * frozen and no one would thaw it. 142 */ 143 int thaw_process(struct task_struct *p) 144 { 145 task_lock(p); 146 if (__thaw_process(p) == 1) { 147 task_unlock(p); 148 wake_up_process(p); 149 return 1; 150 } 151 task_unlock(p); 152 return 0; 153 } 154 EXPORT_SYMBOL(thaw_process); 155