Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -204,8 +204,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
		return -EINVAL;
	}

	lock_device_hotplug();

	/*
	 * Carry out two passes here and ignore errors in the first pass,
	 * because if the devices in question are memory blocks and
@@ -236,9 +234,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
					    ACPI_UINT32_MAX,
					    acpi_bus_online_companions, NULL,
					    NULL, NULL);

			unlock_device_hotplug();

			put_device(&device->dev);
			return -EBUSY;
		}
@@ -249,8 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)

	acpi_bus_trim(device);

	unlock_device_hotplug();

	/* Device node has been unregistered. */
	put_device(&device->dev);
	device = NULL;
@@ -289,6 +282,7 @@ static void acpi_bus_device_eject(void *context)
	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
	int error;

	lock_device_hotplug();
	mutex_lock(&acpi_scan_lock);

	acpi_bus_get_device(handle, &device);
@@ -312,6 +306,7 @@ static void acpi_bus_device_eject(void *context)

 out:
	mutex_unlock(&acpi_scan_lock);
	unlock_device_hotplug();
	return;

 err_out:
@@ -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;
	int error;

	mutex_lock(&acpi_scan_lock);
	lock_device_hotplug();
	mutex_lock(&acpi_scan_lock);

	if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
		acpi_bus_get_device(handle, &device);
@@ -353,9 +348,9 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
		kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);

 out:
	unlock_device_hotplug();
	acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
	mutex_unlock(&acpi_scan_lock);
	unlock_device_hotplug();
}

static void acpi_scan_bus_check(void *context)
@@ -446,6 +441,7 @@ void acpi_bus_hot_remove_device(void *context)
	acpi_handle handle = device->handle;
	int error;

	lock_device_hotplug();
	mutex_lock(&acpi_scan_lock);

	error = acpi_scan_hot_remove(device);
@@ -455,6 +451,7 @@ void acpi_bus_hot_remove_device(void *context)
					  NULL);

	mutex_unlock(&acpi_scan_lock);
	unlock_device_hotplug();
	kfree(context);
}
EXPORT_SYMBOL(acpi_bus_hot_remove_device);
+23 −22
Original line number Diff line number Diff line
@@ -644,22 +644,23 @@ int hibernate(void)
	if (error)
		goto Exit;

	/* Allocate memory management structures */
	error = create_basic_memory_bitmaps();
	if (error)
		goto Exit;

	printk(KERN_INFO "PM: Syncing filesystems ... ");
	sys_sync();
	printk("done.\n");

	error = freeze_processes();
	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);
	if (error || freezer_test_done)
		goto Thaw;
		goto Free_bitmaps;

	if (in_suspend) {
		unsigned int flags = 0;
@@ -682,14 +683,14 @@ int hibernate(void)
		pr_debug("PM: Image restored successfully.\n");
	}

 Free_bitmaps:
	free_basic_memory_bitmaps();
 Thaw:
	unlock_device_hotplug();
	thaw_processes();

	/* Don't bother checking whether freezer_test_done is true */
	freezer_test_done = false;

 Free_bitmaps:
	free_basic_memory_bitmaps();
 Exit:
	pm_notifier_call_chain(PM_POST_HIBERNATION);
	pm_restore_console();
@@ -806,21 +807,20 @@ static int software_resume(void)
	pm_prepare_console();
	error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
	if (error)
		goto close_finish;

	error = create_basic_memory_bitmaps();
	if (error)
		goto close_finish;
		goto Close_Finish;

	pr_debug("PM: Preparing processes for restore.\n");
	error = freeze_processes();
	if (error) {
		swsusp_close(FMODE_READ);
		goto Done;
	}
	if (error)
		goto Close_Finish;

	pr_debug("PM: Loading hibernation image.\n");

	lock_device_hotplug();
	error = create_basic_memory_bitmaps();
	if (error)
		goto Thaw;

	error = swsusp_read(&flags);
	swsusp_close(FMODE_READ);
	if (!error)
@@ -828,9 +828,10 @@ static int software_resume(void)

	printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
	swsusp_free();
	thaw_processes();
 Done:
	free_basic_memory_bitmaps();
 Thaw:
	unlock_device_hotplug();
	thaw_processes();
 Finish:
	pm_notifier_call_chain(PM_POST_RESTORE);
	pm_restore_console();
@@ -840,7 +841,7 @@ static int software_resume(void)
	mutex_unlock(&pm_mutex);
	pr_debug("PM: Hibernation image not present or could not be loaded.\n");
	return error;
close_finish:
 Close_Finish:
	swsusp_close(FMODE_READ);
	goto Finish;
}
+14 −10
Original line number Diff line number Diff line
@@ -60,11 +60,6 @@ static int snapshot_open(struct inode *inode, struct file *filp)
		error = -ENOSYS;
		goto Unlock;
	}
	if(create_basic_memory_bitmaps()) {
		atomic_inc(&snapshot_device_available);
		error = -ENOMEM;
		goto Unlock;
	}
	nonseekable_open(inode, filp);
	data = &snapshot_state;
	filp->private_data = data;
@@ -90,10 +85,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
		if (error)
			pm_notifier_call_chain(PM_POST_RESTORE);
	}
	if (error) {
		free_basic_memory_bitmaps();
	if (error)
		atomic_inc(&snapshot_device_available);
	}

	data->frozen = 0;
	data->ready = 0;
	data->platform_support = 0;
@@ -111,11 +105,11 @@ static int snapshot_release(struct inode *inode, struct file *filp)
	lock_system_sleep();

	swsusp_free();
	free_basic_memory_bitmaps();
	data = filp->private_data;
	free_all_swap_pages(data->swap);
	if (data->frozen) {
		pm_restore_gfp_mask();
		free_basic_memory_bitmaps();
		thaw_processes();
	}
	pm_notifier_call_chain(data->mode == O_RDONLY ?
@@ -207,6 +201,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
	if (!mutex_trylock(&pm_mutex))
		return -EBUSY;

	lock_device_hotplug();
	data = filp->private_data;

	switch (cmd) {
@@ -220,14 +215,22 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
		printk("done.\n");

		error = freeze_processes();
		if (!error)
		if (error)
			break;

		error = create_basic_memory_bitmaps();
		if (error)
			thaw_processes();
		else
			data->frozen = 1;

		break;

	case SNAPSHOT_UNFREEZE:
		if (!data->frozen || data->ready)
			break;
		pm_restore_gfp_mask();
		free_basic_memory_bitmaps();
		thaw_processes();
		data->frozen = 0;
		break;
@@ -371,6 +374,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,

	}

	unlock_device_hotplug();
	mutex_unlock(&pm_mutex);

	return error;
+0 −4
Original line number Diff line number Diff line
@@ -51,14 +51,10 @@ DEFINE_MUTEX(mem_hotplug_mutex);
void lock_memory_hotplug(void)
{
	mutex_lock(&mem_hotplug_mutex);

	/* for exclusive hibernation if CONFIG_HIBERNATION=y */
	lock_system_sleep();
}

void unlock_memory_hotplug(void)
{
	unlock_system_sleep();
	mutex_unlock(&mem_hotplug_mutex);
}