diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-10 17:14:53 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-10 17:14:53 -0400 |
| commit | 85fb0a1c35d86ed9a4de8d6cba79ba0801f7a1f7 (patch) | |
| tree | 4373e14df0aa4064e64cf318edd3e07f5e162270 /kernel/power | |
| parent | a9238741987386bb549d61572973c7e62b2a4145 (diff) | |
| parent | 942f40155a743f4204308d62405dacaa4bfadb11 (diff) | |
Merge branch 'acpi-hotplug'
* acpi-hotplug:
PM / hibernate / memory hotplug: Rework mutual exclusion
PM / hibernate: Create memory bitmaps after freezing user space
ACPI / scan: Change ordering of locks for device hotplug
Diffstat (limited to 'kernel/power')
| -rw-r--r-- | kernel/power/hibernate.c | 45 | ||||
| -rw-r--r-- | kernel/power/user.c | 24 |
2 files changed, 37 insertions, 32 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index b26f5f1e773e..0b78f72ad39d 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
| @@ -644,22 +644,23 @@ int hibernate(void) | |||
| 644 | if (error) | 644 | if (error) |
| 645 | goto Exit; | 645 | goto Exit; |
| 646 | 646 | ||
| 647 | /* Allocate memory management structures */ | ||
| 648 | error = create_basic_memory_bitmaps(); | ||
| 649 | if (error) | ||
| 650 | goto Exit; | ||
| 651 | |||
| 652 | printk(KERN_INFO "PM: Syncing filesystems ... "); | 647 | printk(KERN_INFO "PM: Syncing filesystems ... "); |
| 653 | sys_sync(); | 648 | sys_sync(); |
| 654 | printk("done.\n"); | 649 | printk("done.\n"); |
| 655 | 650 | ||
| 656 | error = freeze_processes(); | 651 | error = freeze_processes(); |
| 657 | if (error) | 652 | if (error) |
| 658 | goto Free_bitmaps; | 653 | goto Exit; |
| 654 | |||
| 655 | lock_device_hotplug(); | ||
| 656 | /* Allocate memory management structures */ | ||
| 657 | error = create_basic_memory_bitmaps(); | ||
| 658 | if (error) | ||
| 659 | goto Thaw; | ||
| 659 | 660 | ||
| 660 | error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); | 661 | error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); |
| 661 | if (error || freezer_test_done) | 662 | if (error || freezer_test_done) |
| 662 | goto Thaw; | 663 | goto Free_bitmaps; |
| 663 | 664 | ||
| 664 | if (in_suspend) { | 665 | if (in_suspend) { |
| 665 | unsigned int flags = 0; | 666 | unsigned int flags = 0; |
| @@ -682,14 +683,14 @@ int hibernate(void) | |||
| 682 | pr_debug("PM: Image restored successfully.\n"); | 683 | pr_debug("PM: Image restored successfully.\n"); |
| 683 | } | 684 | } |
| 684 | 685 | ||
| 686 | Free_bitmaps: | ||
| 687 | free_basic_memory_bitmaps(); | ||
| 685 | Thaw: | 688 | Thaw: |
| 689 | unlock_device_hotplug(); | ||
| 686 | thaw_processes(); | 690 | thaw_processes(); |
| 687 | 691 | ||
| 688 | /* Don't bother checking whether freezer_test_done is true */ | 692 | /* Don't bother checking whether freezer_test_done is true */ |
| 689 | freezer_test_done = false; | 693 | freezer_test_done = false; |
| 690 | |||
| 691 | Free_bitmaps: | ||
| 692 | free_basic_memory_bitmaps(); | ||
| 693 | Exit: | 694 | Exit: |
| 694 | pm_notifier_call_chain(PM_POST_HIBERNATION); | 695 | pm_notifier_call_chain(PM_POST_HIBERNATION); |
| 695 | pm_restore_console(); | 696 | pm_restore_console(); |
| @@ -806,21 +807,20 @@ static int software_resume(void) | |||
| 806 | pm_prepare_console(); | 807 | pm_prepare_console(); |
| 807 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | 808 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
| 808 | if (error) | 809 | if (error) |
| 809 | goto close_finish; | 810 | goto Close_Finish; |
| 810 | |||
| 811 | error = create_basic_memory_bitmaps(); | ||
| 812 | if (error) | ||
| 813 | goto close_finish; | ||
| 814 | 811 | ||
| 815 | pr_debug("PM: Preparing processes for restore.\n"); | 812 | pr_debug("PM: Preparing processes for restore.\n"); |
| 816 | error = freeze_processes(); | 813 | error = freeze_processes(); |
| 817 | if (error) { | 814 | if (error) |
| 818 | swsusp_close(FMODE_READ); | 815 | goto Close_Finish; |
| 819 | goto Done; | ||
| 820 | } | ||
| 821 | 816 | ||
| 822 | pr_debug("PM: Loading hibernation image.\n"); | 817 | pr_debug("PM: Loading hibernation image.\n"); |
| 823 | 818 | ||
| 819 | lock_device_hotplug(); | ||
| 820 | error = create_basic_memory_bitmaps(); | ||
| 821 | if (error) | ||
| 822 | goto Thaw; | ||
| 823 | |||
| 824 | error = swsusp_read(&flags); | 824 | error = swsusp_read(&flags); |
| 825 | swsusp_close(FMODE_READ); | 825 | swsusp_close(FMODE_READ); |
| 826 | if (!error) | 826 | if (!error) |
| @@ -828,9 +828,10 @@ static int software_resume(void) | |||
| 828 | 828 | ||
| 829 | printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n"); | 829 | printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n"); |
| 830 | swsusp_free(); | 830 | swsusp_free(); |
| 831 | thaw_processes(); | ||
| 832 | Done: | ||
| 833 | free_basic_memory_bitmaps(); | 831 | free_basic_memory_bitmaps(); |
| 832 | Thaw: | ||
| 833 | unlock_device_hotplug(); | ||
| 834 | thaw_processes(); | ||
| 834 | Finish: | 835 | Finish: |
| 835 | pm_notifier_call_chain(PM_POST_RESTORE); | 836 | pm_notifier_call_chain(PM_POST_RESTORE); |
| 836 | pm_restore_console(); | 837 | pm_restore_console(); |
| @@ -840,7 +841,7 @@ static int software_resume(void) | |||
| 840 | mutex_unlock(&pm_mutex); | 841 | mutex_unlock(&pm_mutex); |
| 841 | pr_debug("PM: Hibernation image not present or could not be loaded.\n"); | 842 | pr_debug("PM: Hibernation image not present or could not be loaded.\n"); |
| 842 | return error; | 843 | return error; |
| 843 | close_finish: | 844 | Close_Finish: |
| 844 | swsusp_close(FMODE_READ); | 845 | swsusp_close(FMODE_READ); |
| 845 | goto Finish; | 846 | goto Finish; |
| 846 | } | 847 | } |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 4ed81e74f86f..72e8f4fd616d 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
| @@ -60,11 +60,6 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
| 60 | error = -ENOSYS; | 60 | error = -ENOSYS; |
| 61 | goto Unlock; | 61 | goto Unlock; |
| 62 | } | 62 | } |
| 63 | if(create_basic_memory_bitmaps()) { | ||
| 64 | atomic_inc(&snapshot_device_available); | ||
| 65 | error = -ENOMEM; | ||
| 66 | goto Unlock; | ||
| 67 | } | ||
| 68 | nonseekable_open(inode, filp); | 63 | nonseekable_open(inode, filp); |
| 69 | data = &snapshot_state; | 64 | data = &snapshot_state; |
| 70 | filp->private_data = data; | 65 | filp->private_data = data; |
| @@ -90,10 +85,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
| 90 | if (error) | 85 | if (error) |
| 91 | pm_notifier_call_chain(PM_POST_RESTORE); | 86 | pm_notifier_call_chain(PM_POST_RESTORE); |
| 92 | } | 87 | } |
| 93 | if (error) { | 88 | if (error) |
| 94 | free_basic_memory_bitmaps(); | ||
| 95 | atomic_inc(&snapshot_device_available); | 89 | atomic_inc(&snapshot_device_available); |
| 96 | } | 90 | |
| 97 | data->frozen = 0; | 91 | data->frozen = 0; |
| 98 | data->ready = 0; | 92 | data->ready = 0; |
| 99 | data->platform_support = 0; | 93 | data->platform_support = 0; |
| @@ -111,11 +105,11 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
| 111 | lock_system_sleep(); | 105 | lock_system_sleep(); |
| 112 | 106 | ||
| 113 | swsusp_free(); | 107 | swsusp_free(); |
| 114 | free_basic_memory_bitmaps(); | ||
| 115 | data = filp->private_data; | 108 | data = filp->private_data; |
| 116 | free_all_swap_pages(data->swap); | 109 | free_all_swap_pages(data->swap); |
| 117 | if (data->frozen) { | 110 | if (data->frozen) { |
| 118 | pm_restore_gfp_mask(); | 111 | pm_restore_gfp_mask(); |
| 112 | free_basic_memory_bitmaps(); | ||
| 119 | thaw_processes(); | 113 | thaw_processes(); |
| 120 | } | 114 | } |
| 121 | pm_notifier_call_chain(data->mode == O_RDONLY ? | 115 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
| @@ -207,6 +201,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
| 207 | if (!mutex_trylock(&pm_mutex)) | 201 | if (!mutex_trylock(&pm_mutex)) |
| 208 | return -EBUSY; | 202 | return -EBUSY; |
| 209 | 203 | ||
| 204 | lock_device_hotplug(); | ||
| 210 | data = filp->private_data; | 205 | data = filp->private_data; |
| 211 | 206 | ||
| 212 | switch (cmd) { | 207 | switch (cmd) { |
| @@ -220,14 +215,22 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
| 220 | printk("done.\n"); | 215 | printk("done.\n"); |
| 221 | 216 | ||
| 222 | error = freeze_processes(); | 217 | error = freeze_processes(); |
| 223 | if (!error) | 218 | if (error) |
| 219 | break; | ||
| 220 | |||
| 221 | error = create_basic_memory_bitmaps(); | ||
| 222 | if (error) | ||
| 223 | thaw_processes(); | ||
| 224 | else | ||
| 224 | data->frozen = 1; | 225 | data->frozen = 1; |
| 226 | |||
| 225 | break; | 227 | break; |
| 226 | 228 | ||
| 227 | case SNAPSHOT_UNFREEZE: | 229 | case SNAPSHOT_UNFREEZE: |
| 228 | if (!data->frozen || data->ready) | 230 | if (!data->frozen || data->ready) |
| 229 | break; | 231 | break; |
| 230 | pm_restore_gfp_mask(); | 232 | pm_restore_gfp_mask(); |
| 233 | free_basic_memory_bitmaps(); | ||
| 231 | thaw_processes(); | 234 | thaw_processes(); |
| 232 | data->frozen = 0; | 235 | data->frozen = 0; |
| 233 | break; | 236 | break; |
| @@ -371,6 +374,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
| 371 | 374 | ||
| 372 | } | 375 | } |
| 373 | 376 | ||
| 377 | unlock_device_hotplug(); | ||
| 374 | mutex_unlock(&pm_mutex); | 378 | mutex_unlock(&pm_mutex); |
| 375 | 379 | ||
| 376 | return error; | 380 | return error; |
