Commit 25913052 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

[PATCH] swsusp: Change code ordering in user.c

Change the ordering of code in kernel/power/user.c so that device_suspend() is
called before disable_nonboot_cpus() and device_resume() is called after
enable_nonboot_cpus().  This is needed to make the userland suspend call
pm_ops->finish() after enable_nonboot_cpus() and before device_resume(), as
indicated by the recent discussion on Linux-PM (cf.
http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html).

The changes here only affect the userland interface of swsusp.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Cc: Greg KH <greg@kroah.com>
Cc: Nigel Cunningham <nigel@suspend2.net>
Cc: Patrick Mochel <mochel@digitalimplant.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ed746e3b
......@@ -122,6 +122,59 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
return res;
}
static inline int snapshot_suspend(void)
{
int error;
mutex_lock(&pm_mutex);
/* Free memory before shutting down devices. */
error = swsusp_shrink_memory();
if (error)
goto Finish;
suspend_console();
error = device_suspend(PMSG_FREEZE);
if (error)
goto Resume_devices;
error = disable_nonboot_cpus();
if (!error) {
in_suspend = 1;
error = swsusp_suspend();
}
enable_nonboot_cpus();
Resume_devices:
device_resume();
resume_console();
Finish:
mutex_unlock(&pm_mutex);
return error;
}
static inline int snapshot_restore(void)
{
int error;
mutex_lock(&pm_mutex);
pm_prepare_console();
suspend_console();
error = device_suspend(PMSG_PRETHAW);
if (error)
goto Resume_devices;
error = disable_nonboot_cpus();
if (!error)
error = swsusp_resume();
enable_nonboot_cpus();
Resume_devices:
device_resume();
resume_console();
pm_restore_console();
mutex_unlock(&pm_mutex);
return error;
}
static int snapshot_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
......@@ -145,14 +198,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
if (data->frozen)
break;
mutex_lock(&pm_mutex);
error = disable_nonboot_cpus();
if (!error) {
error = freeze_processes();
if (error) {
thaw_processes();
enable_nonboot_cpus();
error = -EBUSY;
}
if (freeze_processes()) {
thaw_processes();
error = -EBUSY;
}
mutex_unlock(&pm_mutex);
if (!error)
......@@ -164,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
break;
mutex_lock(&pm_mutex);
thaw_processes();
enable_nonboot_cpus();
mutex_unlock(&pm_mutex);
data->frozen = 0;
break;
......@@ -174,20 +221,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -EPERM;
break;
}
mutex_lock(&pm_mutex);
/* Free memory before shutting down devices. */
error = swsusp_shrink_memory();
if (!error) {
suspend_console();
error = device_suspend(PMSG_FREEZE);
if (!error) {
in_suspend = 1;
error = swsusp_suspend();
device_resume();
}
resume_console();
}
mutex_unlock(&pm_mutex);
error = snapshot_suspend();
if (!error)
error = put_user(in_suspend, (unsigned int __user *)arg);
if (!error)
......@@ -201,17 +235,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -EPERM;
break;
}
mutex_lock(&pm_mutex);
pm_prepare_console();
suspend_console();
error = device_suspend(PMSG_PRETHAW);
if (!error) {
error = swsusp_resume();
device_resume();
}
resume_console();
pm_restore_console();
mutex_unlock(&pm_mutex);
error = snapshot_restore();
break;
case SNAPSHOT_FREE:
......
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