diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-23 18:11:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-23 18:11:27 -0500 |
commit | ac1e3d4f5c1097422c6e72aeae322033e9a8c803 (patch) | |
tree | adcebdad5f515a8453bfe48940822f57a6904c9d | |
parent | eaed435a7b870a38d89dbdb535c7842d618d3214 (diff) | |
parent | e4c89a508f4385a0cd8681c2749a2cd2fa476e40 (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.txt | 2 | ||||
-rw-r--r-- | Documentation/power/freezing-of-tasks.txt | 8 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 3 | ||||
-rw-r--r-- | include/linux/suspend.h | 19 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 3 |
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, | |||
15 | because some problems only show up on a second attempt at suspending and | 15 | because some problems only show up on a second attempt at suspending and |
16 | resuming the system.] Moreover, hibernating in the "reboot" and "shutdown" | 16 | resuming the system.] Moreover, hibernating in the "reboot" and "shutdown" |
17 | modes causes the PM core to skip some platform-related callbacks which on ACPI | 17 | modes causes the PM core to skip some platform-related callbacks which on ACPI |
18 | systems might be necessary to make hibernation work. Thus, if you machine fails | 18 | systems might be necessary to make hibernation work. Thus, if your machine fails |
19 | to hibernate or resume in the "reboot" mode, you should try the "platform" mode: | 19 | to 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 | |||
120 | freezing user threads I don't find really objectionable." | 120 | freezing user threads I don't find really objectionable." |
121 | 121 | ||
122 | Still, there are kernel threads that may want to be freezable. For example, if | 122 | Still, there are kernel threads that may want to be freezable. For example, if |
123 | a kernel that belongs to a device driver accesses the device directly, it in | 123 | a kernel thread that belongs to a device driver accesses the device directly, it |
124 | principle needs to know when the device is suspended, so that it doesn't try to | 124 | in principle needs to know when the device is suspended, so that it doesn't try |
125 | access it at that time. However, if the kernel thread is freezable, it will be | 125 | to access it at that time. However, if the kernel thread is freezable, it will |
126 | frozen before the driver's .suspend() callback is executed and it will be | 126 | be frozen before the driver's .suspend() callback is executed and it will be |
127 | thawed after the driver's .resume() callback has run, so it won't be accessing | 127 | thawed after the driver's .resume() callback has run, so it won't be accessing |
128 | the device while it's suspended. | 128 | the 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 | ||
358 | static inline void lock_system_sleep(void) | 358 | static 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 | ||
364 | static inline void unlock_system_sleep(void) | 364 | static 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 | ||