process.c (f68ec0c24755e5cdb779be6240925f2175311d84) | process.c (8174f1503f4bf7e9a14b3fbbfdb30c6be6e29f77) |
---|---|
1/* 2 * drivers/power/process.c - Functions for starting/stopping processes on 3 * suspend transitions. 4 * 5 * Originally from swsusp. 6 */ 7 8 --- 14 unchanged lines hidden (view full) --- 23{ 24 if ((p == current) || 25 (p->flags & PF_NOFREEZE) || 26 (p->exit_state != 0)) 27 return 0; 28 return 1; 29} 30 | 1/* 2 * drivers/power/process.c - Functions for starting/stopping processes on 3 * suspend transitions. 4 * 5 * Originally from swsusp. 6 */ 7 8 --- 14 unchanged lines hidden (view full) --- 23{ 24 if ((p == current) || 25 (p->flags & PF_NOFREEZE) || 26 (p->exit_state != 0)) 27 return 0; 28 return 1; 29} 30 |
31/* 32 * freezing is complete, mark current process as frozen 33 */ 34static inline void frozen_process(void) 35{ 36 if (!unlikely(current->flags & PF_NOFREEZE)) { 37 current->flags |= PF_FROZEN; 38 wmb(); 39 } 40 clear_freeze_flag(current); 41} 42 43/* Refrigerator is place where frozen processes are stored :-). */ 44void refrigerator(void) 45{ 46 /* Hmm, should we be allowed to suspend when there are realtime 47 processes around? */ 48 long save; 49 50 task_lock(current); 51 if (freezing(current)) { 52 frozen_process(); 53 task_unlock(current); 54 } else { 55 task_unlock(current); 56 return; 57 } 58 save = current->state; 59 pr_debug("%s entered refrigerator\n", current->comm); 60 61 spin_lock_irq(¤t->sighand->siglock); 62 recalc_sigpending(); /* We sent fake signal, clean it up */ 63 spin_unlock_irq(¤t->sighand->siglock); 64 65 for (;;) { 66 set_current_state(TASK_UNINTERRUPTIBLE); 67 if (!frozen(current)) 68 break; 69 schedule(); 70 } 71 pr_debug("%s left refrigerator\n", current->comm); 72 __set_current_state(save); 73} 74 75static void fake_signal_wake_up(struct task_struct *p) 76{ 77 unsigned long flags; 78 79 spin_lock_irqsave(&p->sighand->siglock, flags); 80 signal_wake_up(p, 0); 81 spin_unlock_irqrestore(&p->sighand->siglock, flags); 82} 83 84static inline bool should_send_signal(struct task_struct *p) 85{ 86 return !(p->flags & PF_FREEZER_NOSIG); 87} 88 89/** 90 * freeze_task - send a freeze request to given task 91 * @p: task to send the request to 92 * @sig_only: if set, the request will only be sent if the task has the 93 * PF_FREEZER_NOSIG flag unset 94 * Return value: 'false', if @sig_only is set and the task has 95 * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise 96 * 97 * The freeze request is sent by setting the tasks's TIF_FREEZE flag and 98 * either sending a fake signal to it or waking it up, depending on whether 99 * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task 100 * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its 101 * TIF_FREEZE flag will not be set. 102 */ 103static bool freeze_task(struct task_struct *p, bool sig_only) 104{ 105 /* 106 * We first check if the task is freezing and next if it has already 107 * been frozen to avoid the race with frozen_process() which first marks 108 * the task as frozen and next clears its TIF_FREEZE. 109 */ 110 if (!freezing(p)) { 111 rmb(); 112 if (frozen(p)) 113 return false; 114 115 if (!sig_only || should_send_signal(p)) 116 set_freeze_flag(p); 117 else 118 return false; 119 } 120 121 if (should_send_signal(p)) { 122 if (!signal_pending(p)) 123 fake_signal_wake_up(p); 124 } else if (sig_only) { 125 return false; 126 } else { 127 wake_up_state(p, TASK_INTERRUPTIBLE); 128 } 129 130 return true; 131} 132 133static void cancel_freezing(struct task_struct *p) 134{ 135 unsigned long flags; 136 137 if (freezing(p)) { 138 pr_debug(" clean up: %s\n", p->comm); 139 clear_freeze_flag(p); 140 spin_lock_irqsave(&p->sighand->siglock, flags); 141 recalc_sigpending_and_wake(p); 142 spin_unlock_irqrestore(&p->sighand->siglock, flags); 143 } 144} 145 | |
146static int try_to_freeze_tasks(bool sig_only) 147{ 148 struct task_struct *g, *p; 149 unsigned long end_time; 150 unsigned int todo; 151 struct timeval start, end; 152 u64 elapsed_csecs64; 153 unsigned int elapsed_csecs; --- 105 unchanged lines hidden (view full) --- 259{ 260 printk("Restarting tasks ... "); 261 thaw_tasks(true); 262 thaw_tasks(false); 263 schedule(); 264 printk("done.\n"); 265} 266 | 31static int try_to_freeze_tasks(bool sig_only) 32{ 33 struct task_struct *g, *p; 34 unsigned long end_time; 35 unsigned int todo; 36 struct timeval start, end; 37 u64 elapsed_csecs64; 38 unsigned int elapsed_csecs; --- 105 unchanged lines hidden (view full) --- 144{ 145 printk("Restarting tasks ... "); 146 thaw_tasks(true); 147 thaw_tasks(false); 148 schedule(); 149 printk("done.\n"); 150} 151 |
267EXPORT_SYMBOL(refrigerator); | |