aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/freezer.h1
-rw-r--r--kernel/freezer.c25
-rw-r--r--kernel/power/hibernate.c15
-rw-r--r--kernel/power/process.c16
-rw-r--r--kernel/power/suspend.c8
-rw-r--r--kernel/power/user.c4
6 files changed, 23 insertions, 46 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index ba4f512d2938..93f411a52872 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -61,7 +61,6 @@ static inline bool try_to_freeze(void)
61} 61}
62 62
63extern bool freeze_task(struct task_struct *p, bool sig_only); 63extern bool freeze_task(struct task_struct *p, bool sig_only);
64extern void cancel_freezing(struct task_struct *p);
65 64
66#ifdef CONFIG_CGROUP_FREEZER 65#ifdef CONFIG_CGROUP_FREEZER
67extern int cgroup_freezing_or_frozen(struct task_struct *task); 66extern int cgroup_freezing_or_frozen(struct task_struct *task);
diff --git a/kernel/freezer.c b/kernel/freezer.c
index b8b562124ba9..11e32d419dec 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -129,21 +129,6 @@ out_unlock:
129 return ret; 129 return ret;
130} 130}
131 131
132void cancel_freezing(struct task_struct *p)
133{
134 unsigned long flags;
135
136 spin_lock_irqsave(&freezer_lock, flags);
137 if (freezing(p)) {
138 pr_debug(" clean up: %s\n", p->comm);
139 clear_freeze_flag(p);
140 spin_lock(&p->sighand->siglock);
141 recalc_sigpending_and_wake(p);
142 spin_unlock(&p->sighand->siglock);
143 }
144 spin_unlock_irqrestore(&freezer_lock, flags);
145}
146
147void __thaw_task(struct task_struct *p) 132void __thaw_task(struct task_struct *p)
148{ 133{
149 unsigned long flags; 134 unsigned long flags;
@@ -153,10 +138,18 @@ void __thaw_task(struct task_struct *p)
153 * be visible to @p as waking up implies wmb. Waking up inside 138 * be visible to @p as waking up implies wmb. Waking up inside
154 * freezer_lock also prevents wakeups from leaking outside 139 * freezer_lock also prevents wakeups from leaking outside
155 * refrigerator. 140 * refrigerator.
141 *
142 * If !FROZEN, @p hasn't reached refrigerator, recalc sigpending to
143 * avoid leaving dangling TIF_SIGPENDING behind.
156 */ 144 */
157 spin_lock_irqsave(&freezer_lock, flags); 145 spin_lock_irqsave(&freezer_lock, flags);
158 clear_freeze_flag(p); 146 clear_freeze_flag(p);
159 if (frozen(p)) 147 if (frozen(p)) {
160 wake_up_process(p); 148 wake_up_process(p);
149 } else {
150 spin_lock(&p->sighand->siglock);
151 recalc_sigpending_and_wake(p);
152 spin_unlock(&p->sighand->siglock);
153 }
161 spin_unlock_irqrestore(&freezer_lock, flags); 154 spin_unlock_irqrestore(&freezer_lock, flags);
162} 155}
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 196c01268ebd..ba2319ffc860 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -607,17 +607,6 @@ static void power_down(void)
607 while(1); 607 while(1);
608} 608}
609 609
610static int prepare_processes(void)
611{
612 int error = 0;
613
614 if (freeze_processes()) {
615 error = -EBUSY;
616 thaw_processes();
617 }
618 return error;
619}
620
621/** 610/**
622 * hibernate - Carry out system hibernation, including saving the image. 611 * hibernate - Carry out system hibernation, including saving the image.
623 */ 612 */
@@ -650,7 +639,7 @@ int hibernate(void)
650 sys_sync(); 639 sys_sync();
651 printk("done.\n"); 640 printk("done.\n");
652 641
653 error = prepare_processes(); 642 error = freeze_processes();
654 if (error) 643 if (error)
655 goto Finish; 644 goto Finish;
656 645
@@ -811,7 +800,7 @@ static int software_resume(void)
811 goto close_finish; 800 goto close_finish;
812 801
813 pr_debug("PM: Preparing processes for restore.\n"); 802 pr_debug("PM: Preparing processes for restore.\n");
814 error = prepare_processes(); 803 error = freeze_processes();
815 if (error) { 804 if (error) {
816 swsusp_close(FMODE_READ); 805 swsusp_close(FMODE_READ);
817 goto Done; 806 goto Done;
diff --git a/kernel/power/process.c b/kernel/power/process.c
index e59676f5811d..ce643838a00c 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -91,11 +91,6 @@ static int try_to_freeze_tasks(bool sig_only)
91 elapsed_csecs = elapsed_csecs64; 91 elapsed_csecs = elapsed_csecs64;
92 92
93 if (todo) { 93 if (todo) {
94 /* This does not unfreeze processes that are already frozen
95 * (we have slightly ugly calling convention in that respect,
96 * and caller must call thaw_processes() if something fails),
97 * but it cleans up leftover PF_FREEZE requests.
98 */
99 printk("\n"); 94 printk("\n");
100 printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " 95 printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
101 "(%d tasks refusing to freeze, wq_busy=%d):\n", 96 "(%d tasks refusing to freeze, wq_busy=%d):\n",
@@ -103,14 +98,11 @@ static int try_to_freeze_tasks(bool sig_only)
103 elapsed_csecs / 100, elapsed_csecs % 100, 98 elapsed_csecs / 100, elapsed_csecs % 100,
104 todo - wq_busy, wq_busy); 99 todo - wq_busy, wq_busy);
105 100
106 thaw_workqueues();
107
108 read_lock(&tasklist_lock); 101 read_lock(&tasklist_lock);
109 do_each_thread(g, p) { 102 do_each_thread(g, p) {
110 if (!wakeup && !freezer_should_skip(p) && 103 if (!wakeup && !freezer_should_skip(p) &&
111 freezing(p) && !frozen(p)) 104 freezing(p) && !frozen(p))
112 sched_show_task(p); 105 sched_show_task(p);
113 cancel_freezing(p);
114 } while_each_thread(g, p); 106 } while_each_thread(g, p);
115 read_unlock(&tasklist_lock); 107 read_unlock(&tasklist_lock);
116 } else { 108 } else {
@@ -123,6 +115,8 @@ static int try_to_freeze_tasks(bool sig_only)
123 115
124/** 116/**
125 * freeze_processes - Signal user space processes to enter the refrigerator. 117 * freeze_processes - Signal user space processes to enter the refrigerator.
118 *
119 * On success, returns 0. On failure, -errno and system is fully thawed.
126 */ 120 */
127int freeze_processes(void) 121int freeze_processes(void)
128{ 122{
@@ -137,11 +131,15 @@ int freeze_processes(void)
137 printk("\n"); 131 printk("\n");
138 BUG_ON(in_atomic()); 132 BUG_ON(in_atomic());
139 133
134 if (error)
135 thaw_processes();
140 return error; 136 return error;
141} 137}
142 138
143/** 139/**
144 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. 140 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
141 *
142 * On success, returns 0. On failure, -errno and system is fully thawed.
145 */ 143 */
146int freeze_kernel_threads(void) 144int freeze_kernel_threads(void)
147{ 145{
@@ -155,6 +153,8 @@ int freeze_kernel_threads(void)
155 printk("\n"); 153 printk("\n");
156 BUG_ON(in_atomic()); 154 BUG_ON(in_atomic());
157 155
156 if (error)
157 thaw_processes();
158 return error; 158 return error;
159} 159}
160 160
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 4953dc054c53..d336b27d1104 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -106,13 +106,11 @@ static int suspend_prepare(void)
106 goto Finish; 106 goto Finish;
107 107
108 error = suspend_freeze_processes(); 108 error = suspend_freeze_processes();
109 if (error) { 109 if (!error)
110 suspend_stats.failed_freeze++;
111 dpm_save_failed_step(SUSPEND_FREEZE);
112 } else
113 return 0; 110 return 0;
114 111
115 suspend_thaw_processes(); 112 suspend_stats.failed_freeze++;
113 dpm_save_failed_step(SUSPEND_FREEZE);
116 usermodehelper_enable(); 114 usermodehelper_enable();
117 Finish: 115 Finish:
118 pm_notifier_call_chain(PM_POST_SUSPEND); 116 pm_notifier_call_chain(PM_POST_SUSPEND);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 6d8f535c2b88..7cc3f5bc5c24 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -257,10 +257,8 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
257 break; 257 break;
258 258
259 error = freeze_processes(); 259 error = freeze_processes();
260 if (error) { 260 if (error)
261 thaw_processes();
262 usermodehelper_enable(); 261 usermodehelper_enable();
263 }
264 if (!error) 262 if (!error)
265 data->frozen = 1; 263 data->frozen = 1;
266 break; 264 break;