aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-10 17:14:53 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-10 17:14:53 -0400
commit85fb0a1c35d86ed9a4de8d6cba79ba0801f7a1f7 (patch)
tree4373e14df0aa4064e64cf318edd3e07f5e162270
parenta9238741987386bb549d61572973c7e62b2a4145 (diff)
parent942f40155a743f4204308d62405dacaa4bfadb11 (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
-rw-r--r--drivers/acpi/scan.c15
-rw-r--r--kernel/power/hibernate.c45
-rw-r--r--kernel/power/user.c24
-rw-r--r--mm/memory_hotplug.c4
4 files changed, 43 insertions, 45 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 61d090b6ce25..fbdb82e70d10 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -204,8 +204,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
204 return -EINVAL; 204 return -EINVAL;
205 } 205 }
206 206
207 lock_device_hotplug();
208
209 /* 207 /*
210 * Carry out two passes here and ignore errors in the first pass, 208 * Carry out two passes here and ignore errors in the first pass,
211 * because if the devices in question are memory blocks and 209 * because if the devices in question are memory blocks and
@@ -236,9 +234,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
236 ACPI_UINT32_MAX, 234 ACPI_UINT32_MAX,
237 acpi_bus_online_companions, NULL, 235 acpi_bus_online_companions, NULL,
238 NULL, NULL); 236 NULL, NULL);
239
240 unlock_device_hotplug();
241
242 put_device(&device->dev); 237 put_device(&device->dev);
243 return -EBUSY; 238 return -EBUSY;
244 } 239 }
@@ -249,8 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
249 244
250 acpi_bus_trim(device); 245 acpi_bus_trim(device);
251 246
252 unlock_device_hotplug();
253
254 /* Device node has been unregistered. */ 247 /* Device node has been unregistered. */
255 put_device(&device->dev); 248 put_device(&device->dev);
256 device = NULL; 249 device = NULL;
@@ -289,6 +282,7 @@ static void acpi_bus_device_eject(void *context)
289 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 282 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
290 int error; 283 int error;
291 284
285 lock_device_hotplug();
292 mutex_lock(&acpi_scan_lock); 286 mutex_lock(&acpi_scan_lock);
293 287
294 acpi_bus_get_device(handle, &device); 288 acpi_bus_get_device(handle, &device);
@@ -312,6 +306,7 @@ static void acpi_bus_device_eject(void *context)
312 306
313 out: 307 out:
314 mutex_unlock(&acpi_scan_lock); 308 mutex_unlock(&acpi_scan_lock);
309 unlock_device_hotplug();
315 return; 310 return;
316 311
317 err_out: 312 err_out:
@@ -326,8 +321,8 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
326 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 321 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
327 int error; 322 int error;
328 323
329 mutex_lock(&acpi_scan_lock);
330 lock_device_hotplug(); 324 lock_device_hotplug();
325 mutex_lock(&acpi_scan_lock);
331 326
332 if (ost_source != ACPI_NOTIFY_BUS_CHECK) { 327 if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
333 acpi_bus_get_device(handle, &device); 328 acpi_bus_get_device(handle, &device);
@@ -353,9 +348,9 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
353 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); 348 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
354 349
355 out: 350 out:
356 unlock_device_hotplug();
357 acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); 351 acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
358 mutex_unlock(&acpi_scan_lock); 352 mutex_unlock(&acpi_scan_lock);
353 unlock_device_hotplug();
359} 354}
360 355
361static void acpi_scan_bus_check(void *context) 356static void acpi_scan_bus_check(void *context)
@@ -446,6 +441,7 @@ void acpi_bus_hot_remove_device(void *context)
446 acpi_handle handle = device->handle; 441 acpi_handle handle = device->handle;
447 int error; 442 int error;
448 443
444 lock_device_hotplug();
449 mutex_lock(&acpi_scan_lock); 445 mutex_lock(&acpi_scan_lock);
450 446
451 error = acpi_scan_hot_remove(device); 447 error = acpi_scan_hot_remove(device);
@@ -455,6 +451,7 @@ void acpi_bus_hot_remove_device(void *context)
455 NULL); 451 NULL);
456 452
457 mutex_unlock(&acpi_scan_lock); 453 mutex_unlock(&acpi_scan_lock);
454 unlock_device_hotplug();
458 kfree(context); 455 kfree(context);
459} 456}
460EXPORT_SYMBOL(acpi_bus_hot_remove_device); 457EXPORT_SYMBOL(acpi_bus_hot_remove_device);
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;
843close_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;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index ca1dd3aa5eee..53ad1325d7a7 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -51,14 +51,10 @@ DEFINE_MUTEX(mem_hotplug_mutex);
51void lock_memory_hotplug(void) 51void lock_memory_hotplug(void)
52{ 52{
53 mutex_lock(&mem_hotplug_mutex); 53 mutex_lock(&mem_hotplug_mutex);
54
55 /* for exclusive hibernation if CONFIG_HIBERNATION=y */
56 lock_system_sleep();
57} 54}
58 55
59void unlock_memory_hotplug(void) 56void unlock_memory_hotplug(void)
60{ 57{
61 unlock_system_sleep();
62 mutex_unlock(&mem_hotplug_mutex); 58 mutex_unlock(&mem_hotplug_mutex);
63} 59}
64 60