xref: /linux/kernel/power/process.c (revision e7d163f7666560c90b163907b9d96ec6207e0f6f)
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 
63 	printk( "Stopping tasks: " );
64 	start_time = jiffies;
65 	do {
66 		todo = 0;
67 		read_lock(&tasklist_lock);
68 		do_each_thread(g, p) {
69 			unsigned long flags;
70 			if (!freezeable(p))
71 				continue;
72 			if ((frozen(p)) ||
73 			    (p->state == TASK_TRACED) ||
74 			    (p->state == TASK_STOPPED))
75 				continue;
76 
77 			freeze(p);
78 			spin_lock_irqsave(&p->sighand->siglock, flags);
79 			signal_wake_up(p, 0);
80 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
81 			todo++;
82 		} while_each_thread(g, p);
83 		read_unlock(&tasklist_lock);
84 		yield();			/* Yield is okay here */
85 		if (time_after(jiffies, start_time + TIMEOUT)) {
86 			printk( "\n" );
87 			printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
88 			return todo;
89 		}
90 	} while(todo);
91 
92 	printk( "|\n" );
93 	BUG_ON(in_atomic());
94 	return 0;
95 }
96 
97 void thaw_processes(void)
98 {
99 	struct task_struct *g, *p;
100 
101 	printk( "Restarting tasks..." );
102 	read_lock(&tasklist_lock);
103 	do_each_thread(g, p) {
104 		if (!freezeable(p))
105 			continue;
106 		if (!thaw_process(p))
107 			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
108 	} while_each_thread(g, p);
109 
110 	read_unlock(&tasklist_lock);
111 	schedule();
112 	printk( " done\n" );
113 }
114 
115 EXPORT_SYMBOL(refrigerator);
116