xref: /linux/kernel/power/process.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /*
2  * drivers/power/process.c - Functions for starting/stopping processes on
3  *                           suspend transitions.
4  *
5  * Originally from swsusp.
6  */
7 
8 
9 #undef DEBUG
10 
11 #include <linux/smp_lock.h>
12 #include <linux/interrupt.h>
13 #include <linux/suspend.h>
14 #include <linux/module.h>
15 #include <linux/syscalls.h>
16 
17 /*
18  * Timeout for stopping processes
19  */
20 #define TIMEOUT	(20 * HZ)
21 
22 
23 static inline int freezeable(struct task_struct * p)
24 {
25 	if ((p == current) ||
26 	    (p->flags & PF_NOFREEZE) ||
27 	    (p->exit_state == EXIT_ZOMBIE) ||
28 	    (p->exit_state == EXIT_DEAD) ||
29 	    (p->state == TASK_STOPPED))
30 		return 0;
31 	return 1;
32 }
33 
34 /* Refrigerator is place where frozen processes are stored :-). */
35 void refrigerator(void)
36 {
37 	/* Hmm, should we be allowed to suspend when there are realtime
38 	   processes around? */
39 	long save;
40 	save = current->state;
41 	pr_debug("%s entered refrigerator\n", current->comm);
42 	printk("=");
43 
44 	frozen_process(current);
45 	spin_lock_irq(&current->sighand->siglock);
46 	recalc_sigpending(); /* We sent fake signal, clean it up */
47 	spin_unlock_irq(&current->sighand->siglock);
48 
49 	while (frozen(current)) {
50 		current->state = TASK_UNINTERRUPTIBLE;
51 		schedule();
52 	}
53 	pr_debug("%s left refrigerator\n", current->comm);
54 	current->state = save;
55 }
56 
57 static inline void freeze_process(struct task_struct *p)
58 {
59 	unsigned long flags;
60 
61 	if (!freezing(p)) {
62 		freeze(p);
63 		spin_lock_irqsave(&p->sighand->siglock, flags);
64 		signal_wake_up(p, 0);
65 		spin_unlock_irqrestore(&p->sighand->siglock, flags);
66 	}
67 }
68 
69 /* 0 = success, else # of processes that we failed to stop */
70 int freeze_processes(void)
71 {
72 	int todo, nr_user, user_frozen;
73 	unsigned long start_time;
74 	struct task_struct *g, *p;
75 	unsigned long flags;
76 
77 	printk( "Stopping tasks: " );
78 	start_time = jiffies;
79 	user_frozen = 0;
80 	do {
81 		nr_user = todo = 0;
82 		read_lock(&tasklist_lock);
83 		do_each_thread(g, p) {
84 			if (!freezeable(p))
85 				continue;
86 			if (frozen(p))
87 				continue;
88 			if (p->mm && !(p->flags & PF_BORROWED_MM)) {
89 				/* The task is a user-space one.
90 				 * Freeze it unless there's a vfork completion
91 				 * pending
92 				 */
93 				if (!p->vfork_done)
94 					freeze_process(p);
95 				nr_user++;
96 			} else {
97 				/* Freeze only if the user space is frozen */
98 				if (user_frozen)
99 					freeze_process(p);
100 				todo++;
101 			}
102 		} while_each_thread(g, p);
103 		read_unlock(&tasklist_lock);
104 		todo += nr_user;
105 		if (!user_frozen && !nr_user) {
106 			sys_sync();
107 			start_time = jiffies;
108 		}
109 		user_frozen = !nr_user;
110 		yield();			/* Yield is okay here */
111 		if (todo && time_after(jiffies, start_time + TIMEOUT))
112 			break;
113 	} while(todo);
114 
115 	/* This does not unfreeze processes that are already frozen
116 	 * (we have slightly ugly calling convention in that respect,
117 	 * and caller must call thaw_processes() if something fails),
118 	 * but it cleans up leftover PF_FREEZE requests.
119 	 */
120 	if (todo) {
121 		printk( "\n" );
122 		printk(KERN_ERR " stopping tasks timed out "
123 			"after %d seconds (%d tasks remaining):\n",
124 			TIMEOUT / HZ, todo);
125 		read_lock(&tasklist_lock);
126 		do_each_thread(g, p) {
127 			if (freezeable(p) && !frozen(p))
128 				printk(KERN_ERR "  %s\n", p->comm);
129 			if (freezing(p)) {
130 				pr_debug("  clean up: %s\n", p->comm);
131 				p->flags &= ~PF_FREEZE;
132 				spin_lock_irqsave(&p->sighand->siglock, flags);
133 				recalc_sigpending_tsk(p);
134 				spin_unlock_irqrestore(&p->sighand->siglock, flags);
135 			}
136 		} while_each_thread(g, p);
137 		read_unlock(&tasklist_lock);
138 		return todo;
139 	}
140 
141 	printk( "|\n" );
142 	BUG_ON(in_atomic());
143 	return 0;
144 }
145 
146 void thaw_processes(void)
147 {
148 	struct task_struct *g, *p;
149 
150 	printk( "Restarting tasks..." );
151 	read_lock(&tasklist_lock);
152 	do_each_thread(g, p) {
153 		if (!freezeable(p))
154 			continue;
155 		if (!thaw_process(p))
156 			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
157 	} while_each_thread(g, p);
158 
159 	read_unlock(&tasklist_lock);
160 	schedule();
161 	printk( " done\n" );
162 }
163 
164 EXPORT_SYMBOL(refrigerator);
165