aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-02-04 18:21:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-02-04 18:21:39 -0500
commit23783f817bceedd6d4e549385e3f400ea64059e5 (patch)
treedb770bd3d7b9264e0f5ed614d9c570d729caf8de
parentd9142025f55973149a854c97e860fff61ed05b37 (diff)
parentd020283dc694c9ec31b410f522252f7a8397e67d (diff)
Merge tag 'pm-fixes-for-3.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Power management fixes for 3.3-rc3 Three power management regression fixes, one for a recent regression introcuded by the freezer changes during the 3.3 merge window and two for regressions in cpuidle (resulting from PM QoS changes) and in the hibernate user space interface, both introduced during the 3.2 development cycle. They include: * Two hibernate (s2disk) regression fixes from Srivatsa S. Bhat (for regressions introduced during the 3.3 merge window and during the 3.2 development cycle). * A cpuidle fix from Venki Pallipadi for a regression resulting from PM QoS changes during the 3.2 development cycle causing cpuidle to work incorrectly for CONFIG_PM unset. * tag 'pm-fixes-for-3.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / QoS: CPU C-state breakage with PM Qos change PM / Freezer: Thaw only kernel threads if freezing of kernel threads fails PM / Hibernate: Thaw kernel threads in SNAPSHOT_CREATE_IMAGE ioctl path
-rw-r--r--include/linux/pm_qos.h14
-rw-r--r--kernel/power/power.h24
-rw-r--r--kernel/power/process.c7
-rw-r--r--kernel/power/user.c6
4 files changed, 44 insertions, 7 deletions
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index e5bbcbaa6f57..4d99e4e6ef83 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -110,7 +110,19 @@ static inline void pm_qos_remove_request(struct pm_qos_request *req)
110 { return; } 110 { return; }
111 111
112static inline int pm_qos_request(int pm_qos_class) 112static inline int pm_qos_request(int pm_qos_class)
113 { return 0; } 113{
114 switch (pm_qos_class) {
115 case PM_QOS_CPU_DMA_LATENCY:
116 return PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
117 case PM_QOS_NETWORK_LATENCY:
118 return PM_QOS_NETWORK_LAT_DEFAULT_VALUE;
119 case PM_QOS_NETWORK_THROUGHPUT:
120 return PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE;
121 default:
122 return PM_QOS_DEFAULT_VALUE;
123 }
124}
125
114static inline int pm_qos_add_notifier(int pm_qos_class, 126static inline int pm_qos_add_notifier(int pm_qos_class,
115 struct notifier_block *notifier) 127 struct notifier_block *notifier)
116 { return 0; } 128 { return 0; }
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 0c4defe6d3b8..21724eee5206 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -231,8 +231,28 @@ extern int pm_test_level;
231#ifdef CONFIG_SUSPEND_FREEZER 231#ifdef CONFIG_SUSPEND_FREEZER
232static inline int suspend_freeze_processes(void) 232static inline int suspend_freeze_processes(void)
233{ 233{
234 int error = freeze_processes(); 234 int error;
235 return error ? : freeze_kernel_threads(); 235
236 error = freeze_processes();
237
238 /*
239 * freeze_processes() automatically thaws every task if freezing
240 * fails. So we need not do anything extra upon error.
241 */
242 if (error)
243 goto Finish;
244
245 error = freeze_kernel_threads();
246
247 /*
248 * freeze_kernel_threads() thaws only kernel threads upon freezing
249 * failure. So we have to thaw the userspace tasks ourselves.
250 */
251 if (error)
252 thaw_processes();
253
254 Finish:
255 return error;
236} 256}
237 257
238static inline void suspend_thaw_processes(void) 258static inline void suspend_thaw_processes(void)
diff --git a/kernel/power/process.c b/kernel/power/process.c
index eeca00311f39..7e426459e60a 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -143,7 +143,10 @@ int freeze_processes(void)
143/** 143/**
144 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. 144 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
145 * 145 *
146 * On success, returns 0. On failure, -errno and system is fully thawed. 146 * On success, returns 0. On failure, -errno and only the kernel threads are
147 * thawed, so as to give a chance to the caller to do additional cleanups
148 * (if any) before thawing the userspace tasks. So, it is the responsibility
149 * of the caller to thaw the userspace tasks, when the time is right.
147 */ 150 */
148int freeze_kernel_threads(void) 151int freeze_kernel_threads(void)
149{ 152{
@@ -159,7 +162,7 @@ int freeze_kernel_threads(void)
159 BUG_ON(in_atomic()); 162 BUG_ON(in_atomic());
160 163
161 if (error) 164 if (error)
162 thaw_processes(); 165 thaw_kernel_threads();
163 return error; 166 return error;
164} 167}
165 168
diff --git a/kernel/power/user.c b/kernel/power/user.c
index e5a21a857302..3e100075b13c 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -249,13 +249,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
249 } 249 }
250 pm_restore_gfp_mask(); 250 pm_restore_gfp_mask();
251 error = hibernation_snapshot(data->platform_support); 251 error = hibernation_snapshot(data->platform_support);
252 if (!error) { 252 if (error) {
253 thaw_kernel_threads();
254 } else {
253 error = put_user(in_suspend, (int __user *)arg); 255 error = put_user(in_suspend, (int __user *)arg);
254 if (!error && !freezer_test_done) 256 if (!error && !freezer_test_done)
255 data->ready = 1; 257 data->ready = 1;
256 if (freezer_test_done) { 258 if (freezer_test_done) {
257 freezer_test_done = false; 259 freezer_test_done = false;
258 thaw_processes(); 260 thaw_kernel_threads();
259 } 261 }
260 } 262 }
261 break; 263 break;