Commit 85fb0a1c authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

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
parents a9238741 942f4015
...@@ -204,8 +204,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device) ...@@ -204,8 +204,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
return -EINVAL; return -EINVAL;
} }
lock_device_hotplug();
/* /*
* Carry out two passes here and ignore errors in the first pass, * Carry out two passes here and ignore errors in the first pass,
* because if the devices in question are memory blocks and * 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,9 +234,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
acpi_bus_online_companions, NULL, acpi_bus_online_companions, NULL,
NULL, NULL); NULL, NULL);
unlock_device_hotplug();
put_device(&device->dev); put_device(&device->dev);
return -EBUSY; return -EBUSY;
} }
...@@ -249,8 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device) ...@@ -249,8 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
acpi_bus_trim(device); acpi_bus_trim(device);
unlock_device_hotplug();
/* Device node has been unregistered. */ /* Device node has been unregistered. */
put_device(&device->dev); put_device(&device->dev);
device = NULL; device = NULL;
...@@ -289,6 +282,7 @@ static void acpi_bus_device_eject(void *context) ...@@ -289,6 +282,7 @@ static void acpi_bus_device_eject(void *context)
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
int error; int error;
lock_device_hotplug();
mutex_lock(&acpi_scan_lock); mutex_lock(&acpi_scan_lock);
acpi_bus_get_device(handle, &device); acpi_bus_get_device(handle, &device);
...@@ -312,6 +306,7 @@ static void acpi_bus_device_eject(void *context) ...@@ -312,6 +306,7 @@ static void acpi_bus_device_eject(void *context)
out: out:
mutex_unlock(&acpi_scan_lock); mutex_unlock(&acpi_scan_lock);
unlock_device_hotplug();
return; return;
err_out: err_out:
...@@ -326,8 +321,8 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) ...@@ -326,8 +321,8 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
int error; int error;
mutex_lock(&acpi_scan_lock);
lock_device_hotplug(); lock_device_hotplug();
mutex_lock(&acpi_scan_lock);
if (ost_source != ACPI_NOTIFY_BUS_CHECK) { if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
acpi_bus_get_device(handle, &device); acpi_bus_get_device(handle, &device);
...@@ -353,9 +348,9 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) ...@@ -353,9 +348,9 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
out: out:
unlock_device_hotplug();
acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
mutex_unlock(&acpi_scan_lock); mutex_unlock(&acpi_scan_lock);
unlock_device_hotplug();
} }
static void acpi_scan_bus_check(void *context) static void acpi_scan_bus_check(void *context)
...@@ -446,6 +441,7 @@ void acpi_bus_hot_remove_device(void *context) ...@@ -446,6 +441,7 @@ void acpi_bus_hot_remove_device(void *context)
acpi_handle handle = device->handle; acpi_handle handle = device->handle;
int error; int error;
lock_device_hotplug();
mutex_lock(&acpi_scan_lock); mutex_lock(&acpi_scan_lock);
error = acpi_scan_hot_remove(device); error = acpi_scan_hot_remove(device);
...@@ -455,6 +451,7 @@ void acpi_bus_hot_remove_device(void *context) ...@@ -455,6 +451,7 @@ void acpi_bus_hot_remove_device(void *context)
NULL); NULL);
mutex_unlock(&acpi_scan_lock); mutex_unlock(&acpi_scan_lock);
unlock_device_hotplug();
kfree(context); kfree(context);
} }
EXPORT_SYMBOL(acpi_bus_hot_remove_device); EXPORT_SYMBOL(acpi_bus_hot_remove_device);
......
...@@ -644,22 +644,23 @@ int hibernate(void) ...@@ -644,22 +644,23 @@ int hibernate(void)
if (error) if (error)
goto Exit; goto Exit;
/* Allocate memory management structures */
error = create_basic_memory_bitmaps();
if (error)
goto Exit;
printk(KERN_INFO "PM: Syncing filesystems ... "); printk(KERN_INFO "PM: Syncing filesystems ... ");
sys_sync(); sys_sync();
printk("done.\n"); printk("done.\n");
error = freeze_processes(); error = freeze_processes();
if (error) if (error)
goto Free_bitmaps; goto Exit;
lock_device_hotplug();
/* Allocate memory management structures */
error = create_basic_memory_bitmaps();
if (error)
goto Thaw;
error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
if (error || freezer_test_done) if (error || freezer_test_done)
goto Thaw; goto Free_bitmaps;
if (in_suspend) { if (in_suspend) {
unsigned int flags = 0; unsigned int flags = 0;
...@@ -682,14 +683,14 @@ int hibernate(void) ...@@ -682,14 +683,14 @@ int hibernate(void)
pr_debug("PM: Image restored successfully.\n"); pr_debug("PM: Image restored successfully.\n");
} }
Free_bitmaps:
free_basic_memory_bitmaps();
Thaw: Thaw:
unlock_device_hotplug();
thaw_processes(); thaw_processes();
/* Don't bother checking whether freezer_test_done is true */ /* Don't bother checking whether freezer_test_done is true */
freezer_test_done = false; freezer_test_done = false;
Free_bitmaps:
free_basic_memory_bitmaps();
Exit: Exit:
pm_notifier_call_chain(PM_POST_HIBERNATION); pm_notifier_call_chain(PM_POST_HIBERNATION);
pm_restore_console(); pm_restore_console();
...@@ -806,21 +807,20 @@ static int software_resume(void) ...@@ -806,21 +807,20 @@ static int software_resume(void)
pm_prepare_console(); pm_prepare_console();
error = pm_notifier_call_chain(PM_RESTORE_PREPARE); error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
if (error) if (error)
goto close_finish; goto Close_Finish;
error = create_basic_memory_bitmaps();
if (error)
goto close_finish;
pr_debug("PM: Preparing processes for restore.\n"); pr_debug("PM: Preparing processes for restore.\n");
error = freeze_processes(); error = freeze_processes();
if (error) { if (error)
swsusp_close(FMODE_READ); goto Close_Finish;
goto Done;
}
pr_debug("PM: Loading hibernation image.\n"); pr_debug("PM: Loading hibernation image.\n");
lock_device_hotplug();
error = create_basic_memory_bitmaps();
if (error)
goto Thaw;
error = swsusp_read(&flags); error = swsusp_read(&flags);
swsusp_close(FMODE_READ); swsusp_close(FMODE_READ);
if (!error) if (!error)
...@@ -828,9 +828,10 @@ static int software_resume(void) ...@@ -828,9 +828,10 @@ static int software_resume(void)
printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n"); printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
swsusp_free(); swsusp_free();
thaw_processes();
Done:
free_basic_memory_bitmaps(); free_basic_memory_bitmaps();
Thaw:
unlock_device_hotplug();
thaw_processes();
Finish: Finish:
pm_notifier_call_chain(PM_POST_RESTORE); pm_notifier_call_chain(PM_POST_RESTORE);
pm_restore_console(); pm_restore_console();
...@@ -840,7 +841,7 @@ static int software_resume(void) ...@@ -840,7 +841,7 @@ static int software_resume(void)
mutex_unlock(&pm_mutex); mutex_unlock(&pm_mutex);
pr_debug("PM: Hibernation image not present or could not be loaded.\n"); pr_debug("PM: Hibernation image not present or could not be loaded.\n");
return error; return error;
close_finish: Close_Finish:
swsusp_close(FMODE_READ); swsusp_close(FMODE_READ);
goto Finish; goto Finish;
} }
......
...@@ -60,11 +60,6 @@ static int snapshot_open(struct inode *inode, struct file *filp) ...@@ -60,11 +60,6 @@ static int snapshot_open(struct inode *inode, struct file *filp)
error = -ENOSYS; error = -ENOSYS;
goto Unlock; goto Unlock;
} }
if(create_basic_memory_bitmaps()) {
atomic_inc(&snapshot_device_available);
error = -ENOMEM;
goto Unlock;
}
nonseekable_open(inode, filp); nonseekable_open(inode, filp);
data = &snapshot_state; data = &snapshot_state;
filp->private_data = data; filp->private_data = data;
...@@ -90,10 +85,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) ...@@ -90,10 +85,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
if (error) if (error)
pm_notifier_call_chain(PM_POST_RESTORE); pm_notifier_call_chain(PM_POST_RESTORE);
} }
if (error) { if (error)
free_basic_memory_bitmaps();
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
}
data->frozen = 0; data->frozen = 0;
data->ready = 0; data->ready = 0;
data->platform_support = 0; data->platform_support = 0;
...@@ -111,11 +105,11 @@ static int snapshot_release(struct inode *inode, struct file *filp) ...@@ -111,11 +105,11 @@ static int snapshot_release(struct inode *inode, struct file *filp)
lock_system_sleep(); lock_system_sleep();
swsusp_free(); swsusp_free();
free_basic_memory_bitmaps();
data = filp->private_data; data = filp->private_data;
free_all_swap_pages(data->swap); free_all_swap_pages(data->swap);
if (data->frozen) { if (data->frozen) {
pm_restore_gfp_mask(); pm_restore_gfp_mask();
free_basic_memory_bitmaps();
thaw_processes(); thaw_processes();
} }
pm_notifier_call_chain(data->mode == O_RDONLY ? pm_notifier_call_chain(data->mode == O_RDONLY ?
...@@ -207,6 +201,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, ...@@ -207,6 +201,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
if (!mutex_trylock(&pm_mutex)) if (!mutex_trylock(&pm_mutex))
return -EBUSY; return -EBUSY;
lock_device_hotplug();
data = filp->private_data; data = filp->private_data;
switch (cmd) { switch (cmd) {
...@@ -220,14 +215,22 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, ...@@ -220,14 +215,22 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
printk("done.\n"); printk("done.\n");
error = freeze_processes(); error = freeze_processes();
if (!error) if (error)
break;
error = create_basic_memory_bitmaps();
if (error)
thaw_processes();
else
data->frozen = 1; data->frozen = 1;
break; break;
case SNAPSHOT_UNFREEZE: case SNAPSHOT_UNFREEZE:
if (!data->frozen || data->ready) if (!data->frozen || data->ready)
break; break;
pm_restore_gfp_mask(); pm_restore_gfp_mask();
free_basic_memory_bitmaps();
thaw_processes(); thaw_processes();
data->frozen = 0; data->frozen = 0;
break; break;
...@@ -371,6 +374,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, ...@@ -371,6 +374,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
} }
unlock_device_hotplug();
mutex_unlock(&pm_mutex); mutex_unlock(&pm_mutex);
return error; return error;
......
...@@ -51,14 +51,10 @@ DEFINE_MUTEX(mem_hotplug_mutex); ...@@ -51,14 +51,10 @@ DEFINE_MUTEX(mem_hotplug_mutex);
void lock_memory_hotplug(void) void lock_memory_hotplug(void)
{ {
mutex_lock(&mem_hotplug_mutex); mutex_lock(&mem_hotplug_mutex);
/* for exclusive hibernation if CONFIG_HIBERNATION=y */
lock_system_sleep();
} }
void unlock_memory_hotplug(void) void unlock_memory_hotplug(void)
{ {
unlock_system_sleep();
mutex_unlock(&mem_hotplug_mutex); mutex_unlock(&mem_hotplug_mutex);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment