Skip to content

Commit 23783f8

Browse files
committed
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
2 parents d914202 + d020283 commit 23783f8

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

include/linux/pm_qos.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,19 @@ static inline void pm_qos_remove_request(struct pm_qos_request *req)
110110
{ return; }
111111

112112
static 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+
114126
static inline int pm_qos_add_notifier(int pm_qos_class,
115127
struct notifier_block *notifier)
116128
{ return 0; }

kernel/power/power.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,28 @@ extern int pm_test_level;
231231
#ifdef CONFIG_SUSPEND_FREEZER
232232
static inline int suspend_freeze_processes(void)
233233
{
234-
int error = freeze_processes();
235-
return error ? : freeze_kernel_threads();
234+
int error;
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;
236256
}
237257

238258
static inline void suspend_thaw_processes(void)

kernel/power/process.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ int freeze_processes(void)
143143
/**
144144
* freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
145145
*
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.
147150
*/
148151
int freeze_kernel_threads(void)
149152
{
@@ -159,7 +162,7 @@ int freeze_kernel_threads(void)
159162
BUG_ON(in_atomic());
160163

161164
if (error)
162-
thaw_processes();
165+
thaw_kernel_threads();
163166
return error;
164167
}
165168

kernel/power/user.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
249249
}
250250
pm_restore_gfp_mask();
251251
error = hibernation_snapshot(data->platform_support);
252-
if (!error) {
252+
if (error) {
253+
thaw_kernel_threads();
254+
} else {
253255
error = put_user(in_suspend, (int __user *)arg);
254256
if (!error && !freezer_test_done)
255257
data->ready = 1;
256258
if (freezer_test_done) {
257259
freezer_test_done = false;
258-
thaw_processes();
260+
thaw_kernel_threads();
259261
}
260262
}
261263
break;

0 commit comments

Comments
 (0)