xref: /linux/kernel/power/process.c (revision 13abf8130139c2ccd4962a7e5a8902be5e6cb5a7)
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 
16 /*
17  * Timeout for stopping processes
18  */
19 #define TIMEOUT	(6 * HZ)
20 
21 
22 static inline int freezeable(struct task_struct * p)
23 {
24 	if ((p == current) ||
25 	    (p->flags & PF_NOFREEZE) ||
26 	    (p->exit_state == EXIT_ZOMBIE) ||
27 	    (p->exit_state == EXIT_DEAD) ||
28 	    (p->state == TASK_STOPPED) ||
29 	    (p->state == TASK_TRACED))
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 /* 0 = success, else # of processes that we failed to stop */
58 int freeze_processes(void)
59 {
60 	int todo;
61 	unsigned long start_time;
62 	struct task_struct *g, *p;
63 	unsigned long flags;
64 
65 	printk( "Stopping tasks: " );
66 	start_time = jiffies;
67 	do {
68 		todo = 0;
69 		read_lock(&tasklist_lock);
70 		do_each_thread(g, p) {
71 			if (!freezeable(p))
72 				continue;
73 			if (frozen(p))
74 				continue;
75 
76 			freeze(p);
77 			spin_lock_irqsave(&p->sighand->siglock, flags);
78 			signal_wake_up(p, 0);
79 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
80 			todo++;
81 		} while_each_thread(g, p);
82 		read_unlock(&tasklist_lock);
83 		yield();			/* Yield is okay here */
84 		if (todo && time_after(jiffies, start_time + TIMEOUT)) {
85 			printk( "\n" );
86 			printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
87 			break;
88 		}
89 	} while(todo);
90 
91 	/* This does not unfreeze processes that are already frozen
92 	 * (we have slightly ugly calling convention in that respect,
93 	 * and caller must call thaw_processes() if something fails),
94 	 * but it cleans up leftover PF_FREEZE requests.
95 	 */
96 	if (todo) {
97 		read_lock(&tasklist_lock);
98 		do_each_thread(g, p)
99 			if (freezing(p)) {
100 				pr_debug("  clean up: %s\n", p->comm);
101 				p->flags &= ~PF_FREEZE;
102 				spin_lock_irqsave(&p->sighand->siglock, flags);
103 				recalc_sigpending_tsk(p);
104 				spin_unlock_irqrestore(&p->sighand->siglock, flags);
105 			}
106 		while_each_thread(g, p);
107 		read_unlock(&tasklist_lock);
108 		return todo;
109 	}
110 
111 	printk( "|\n" );
112 	BUG_ON(in_atomic());
113 	return 0;
114 }
115 
116 void thaw_processes(void)
117 {
118 	struct task_struct *g, *p;
119 
120 	printk( "Restarting tasks..." );
121 	read_lock(&tasklist_lock);
122 	do_each_thread(g, p) {
123 		if (!freezeable(p))
124 			continue;
125 		if (!thaw_process(p))
126 			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
127 	} while_each_thread(g, p);
128 
129 	read_unlock(&tasklist_lock);
130 	schedule();
131 	printk( " done\n" );
132 }
133 
134 EXPORT_SYMBOL(refrigerator);
135