aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-23 18:11:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-23 18:11:27 -0500
commitac1e3d4f5c1097422c6e72aeae322033e9a8c803 (patch)
treeadcebdad5f515a8453bfe48940822f57a6904c9d
parenteaed435a7b870a38d89dbdb535c7842d618d3214 (diff)
parente4c89a508f4385a0cd8681c2749a2cd2fa476e40 (diff)
Merge tag 'pm-fixes-for-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Power management fixes for 3.3 Two fixes for regressions introduced during the merge window, one fix for a long-standing obscure issue in the computation of hibernate image size and two small PM documentation fixes. * tag 'pm-fixes-for-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / Sleep: Fix read_unlock_usermodehelper() call. PM / Hibernate: Rewrite unlock_system_sleep() to fix s2disk regression PM / Hibernate: Correct additional pages number calculation PM / Documentation: Fix minor issue in freezing_of_tasks.txt PM / Documentation: Fix spelling mistake in basic-pm-debugging.txt
-rw-r--r--Documentation/power/basic-pm-debugging.txt2
-rw-r--r--Documentation/power/freezing-of-tasks.txt8
-rw-r--r--drivers/base/firmware_class.c3
-rw-r--r--include/linux/suspend.h19
-rw-r--r--kernel/power/snapshot.c3
5 files changed, 25 insertions, 10 deletions
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 40a4c65f380a..262acf56fa79 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -15,7 +15,7 @@ test at least a couple of times in a row for confidence. [This is necessary,
15because some problems only show up on a second attempt at suspending and 15because some problems only show up on a second attempt at suspending and
16resuming the system.] Moreover, hibernating in the "reboot" and "shutdown" 16resuming the system.] Moreover, hibernating in the "reboot" and "shutdown"
17modes causes the PM core to skip some platform-related callbacks which on ACPI 17modes causes the PM core to skip some platform-related callbacks which on ACPI
18systems might be necessary to make hibernation work. Thus, if you machine fails 18systems might be necessary to make hibernation work. Thus, if your machine fails
19to hibernate or resume in the "reboot" mode, you should try the "platform" mode: 19to hibernate or resume in the "reboot" mode, you should try the "platform" mode:
20 20
21# echo platform > /sys/power/disk 21# echo platform > /sys/power/disk
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 6ccb68f68da6..ebd7490ef1df 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -120,10 +120,10 @@ So in practice, the 'at all' may become a 'why freeze kernel threads?' and
120freezing user threads I don't find really objectionable." 120freezing user threads I don't find really objectionable."
121 121
122Still, there are kernel threads that may want to be freezable. For example, if 122Still, there are kernel threads that may want to be freezable. For example, if
123a kernel that belongs to a device driver accesses the device directly, it in 123a kernel thread that belongs to a device driver accesses the device directly, it
124principle needs to know when the device is suspended, so that it doesn't try to 124in principle needs to know when the device is suspended, so that it doesn't try
125access it at that time. However, if the kernel thread is freezable, it will be 125to access it at that time. However, if the kernel thread is freezable, it will
126frozen before the driver's .suspend() callback is executed and it will be 126be frozen before the driver's .suspend() callback is executed and it will be
127thawed after the driver's .resume() callback has run, so it won't be accessing 127thawed after the driver's .resume() callback has run, so it won't be accessing
128the device while it's suspended. 128the device while it's suspended.
129 129
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 26ab358dac62..6c9387d646ec 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -525,8 +525,7 @@ static int _request_firmware(const struct firmware **firmware_p,
525 if (!firmware) { 525 if (!firmware) {
526 dev_err(device, "%s: kmalloc(struct firmware) failed\n", 526 dev_err(device, "%s: kmalloc(struct firmware) failed\n",
527 __func__); 527 __func__);
528 retval = -ENOMEM; 528 return -ENOMEM;
529 goto out;
530 } 529 }
531 530
532 if (fw_get_builtin_firmware(firmware, name)) { 531 if (fw_get_builtin_firmware(firmware, name)) {
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 95040cc33107..91784a4f8608 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -357,14 +357,29 @@ extern bool pm_save_wakeup_count(unsigned int count);
357 357
358static inline void lock_system_sleep(void) 358static inline void lock_system_sleep(void)
359{ 359{
360 freezer_do_not_count(); 360 current->flags |= PF_FREEZER_SKIP;
361 mutex_lock(&pm_mutex); 361 mutex_lock(&pm_mutex);
362} 362}
363 363
364static inline void unlock_system_sleep(void) 364static inline void unlock_system_sleep(void)
365{ 365{
366 /*
367 * Don't use freezer_count() because we don't want the call to
368 * try_to_freeze() here.
369 *
370 * Reason:
371 * Fundamentally, we just don't need it, because freezing condition
372 * doesn't come into effect until we release the pm_mutex lock,
373 * since the freezer always works with pm_mutex held.
374 *
375 * More importantly, in the case of hibernation,
376 * unlock_system_sleep() gets called in snapshot_read() and
377 * snapshot_write() when the freezing condition is still in effect.
378 * Which means, if we use try_to_freeze() here, it would make them
379 * enter the refrigerator, thus causing hibernation to lockup.
380 */
381 current->flags &= ~PF_FREEZER_SKIP;
366 mutex_unlock(&pm_mutex); 382 mutex_unlock(&pm_mutex);
367 freezer_count();
368} 383}
369 384
370#else /* !CONFIG_PM_SLEEP */ 385#else /* !CONFIG_PM_SLEEP */
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 1cf88900ec4f..6a768e537001 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -812,7 +812,8 @@ unsigned int snapshot_additional_pages(struct zone *zone)
812 unsigned int res; 812 unsigned int res;
813 813
814 res = DIV_ROUND_UP(zone->spanned_pages, BM_BITS_PER_BLOCK); 814 res = DIV_ROUND_UP(zone->spanned_pages, BM_BITS_PER_BLOCK);
815 res += DIV_ROUND_UP(res * sizeof(struct bm_block), PAGE_SIZE); 815 res += DIV_ROUND_UP(res * sizeof(struct bm_block),
816 LINKED_PAGE_DATA_SIZE);
816 return 2 * res; 817 return 2 * res;
817} 818}
818 819