xref: /linux/kernel/power/process.c (revision d67b569f5f620c0fb95d5212642746b7ba9d29e4)
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 	current->state = TASK_UNINTERRUPTIBLE;
42 	pr_debug("%s entered refrigerator\n", current->comm);
43 	printk("=");
44 
45 	frozen_process(current);
46 	spin_lock_irq(&current->sighand->siglock);
47 	recalc_sigpending(); /* We sent fake signal, clean it up */
48 	spin_unlock_irq(&current->sighand->siglock);
49 
50 	while (frozen(current))
51 		schedule();
52 	pr_debug("%s left refrigerator\n", current->comm);
53 	current->state = save;
54 }
55 
56 /* 0 = success, else # of processes that we failed to stop */
57 int freeze_processes(void)
58 {
59 	int todo;
60 	unsigned long start_time;
61 	struct task_struct *g, *p;
62 	unsigned long flags;
63 
64 	printk( "Stopping tasks: " );
65 	start_time = jiffies;
66 	do {
67 		todo = 0;
68 		read_lock(&tasklist_lock);
69 		do_each_thread(g, p) {
70 			if (!freezeable(p))
71 				continue;
72 			if (frozen(p))
73 				continue;
74 
75 			freeze(p);
76 			spin_lock_irqsave(&p->sighand->siglock, flags);
77 			signal_wake_up(p, 0);
78 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
79 			todo++;
80 		} while_each_thread(g, p);
81 		read_unlock(&tasklist_lock);
82 		yield();			/* Yield is okay here */
83 		if (time_after(jiffies, start_time + TIMEOUT)) {
84 			printk( "\n" );
85 			printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
86 			return todo;
87 		}
88 	} while(todo);
89 
90 	printk( "|\n" );
91 	BUG_ON(in_atomic());
92 	return 0;
93 }
94 
95 void thaw_processes(void)
96 {
97 	struct task_struct *g, *p;
98 
99 	printk( "Restarting tasks..." );
100 	read_lock(&tasklist_lock);
101 	do_each_thread(g, p) {
102 		if (!freezeable(p))
103 			continue;
104 		if (!thaw_process(p))
105 			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
106 	} while_each_thread(g, p);
107 
108 	read_unlock(&tasklist_lock);
109 	schedule();
110 	printk( " done\n" );
111 }
112 
113 EXPORT_SYMBOL(refrigerator);
114