diff options
-rw-r--r-- | include/linux/freezer.h | 1 | ||||
-rw-r--r-- | kernel/freezer.c | 25 | ||||
-rw-r--r-- | kernel/power/hibernate.c | 15 | ||||
-rw-r--r-- | kernel/power/process.c | 16 | ||||
-rw-r--r-- | kernel/power/suspend.c | 8 | ||||
-rw-r--r-- | kernel/power/user.c | 4 |
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 | ||
63 | extern bool freeze_task(struct task_struct *p, bool sig_only); | 63 | extern bool freeze_task(struct task_struct *p, bool sig_only); |
64 | extern void cancel_freezing(struct task_struct *p); | ||
65 | 64 | ||
66 | #ifdef CONFIG_CGROUP_FREEZER | 65 | #ifdef CONFIG_CGROUP_FREEZER |
67 | extern int cgroup_freezing_or_frozen(struct task_struct *task); | 66 | extern 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 | ||
132 | void 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 | |||
147 | void __thaw_task(struct task_struct *p) | 132 | void __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 | ||
610 | static 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 | */ |
127 | int freeze_processes(void) | 121 | int 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 | */ |
146 | int freeze_kernel_threads(void) | 144 | int 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; |