mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 06:01:23 +00:00
[PATCH] swsusp: debugging
Add a swsusp debugging mode. This does everything that's needed for a suspend except for actually suspending. So we can look in the log messages and work out a) what code is being slow and b) which drivers are misbehaving. (1) # echo testproc > /sys/power/disk # echo disk > /sys/power/state This should turn off the non-boot CPU, freeze all processes, wait for 5 seconds and then thaw the processes and the CPU. (2) # echo test > /sys/power/disk # echo disk > /sys/power/state This should turn off the non-boot CPU, freeze all processes, shrink memory, suspend all devices, wait for 5 seconds, resume the devices etc. Cc: Pavel Machek <pavel@ucw.cz> Cc: Stefan Seyfried <seife@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
90d5390944
commit
b918f6e62c
4 changed files with 60 additions and 11 deletions
|
@ -21,7 +21,7 @@ Description:
|
||||||
these states.
|
these states.
|
||||||
|
|
||||||
What: /sys/power/disk
|
What: /sys/power/disk
|
||||||
Date: August 2006
|
Date: September 2006
|
||||||
Contact: Rafael J. Wysocki <rjw@sisk.pl>
|
Contact: Rafael J. Wysocki <rjw@sisk.pl>
|
||||||
Description:
|
Description:
|
||||||
The /sys/power/disk file controls the operating mode of the
|
The /sys/power/disk file controls the operating mode of the
|
||||||
|
@ -39,6 +39,19 @@ Description:
|
||||||
'reboot' - the memory image will be saved by the kernel and
|
'reboot' - the memory image will be saved by the kernel and
|
||||||
the system will be rebooted.
|
the system will be rebooted.
|
||||||
|
|
||||||
|
Additionally, /sys/power/disk can be used to turn on one of the
|
||||||
|
two testing modes of the suspend-to-disk mechanism: 'testproc'
|
||||||
|
or 'test'. If the suspend-to-disk mechanism is in the
|
||||||
|
'testproc' mode, writing 'disk' to /sys/power/state will cause
|
||||||
|
the kernel to disable nonboot CPUs and freeze tasks, wait for 5
|
||||||
|
seconds, unfreeze tasks and enable nonboot CPUs. If it is in
|
||||||
|
the 'test' mode, writing 'disk' to /sys/power/state will cause
|
||||||
|
the kernel to disable nonboot CPUs and freeze tasks, shrink
|
||||||
|
memory, suspend devices, wait for 5 seconds, resume devices,
|
||||||
|
unfreeze tasks and enable nonboot CPUs. Then, we are able to
|
||||||
|
look in the log messages and work out, for example, which code
|
||||||
|
is being slow and which device drivers are misbehaving.
|
||||||
|
|
||||||
The suspend-to-disk method may be chosen by writing to this
|
The suspend-to-disk method may be chosen by writing to this
|
||||||
file one of the accepted strings:
|
file one of the accepted strings:
|
||||||
|
|
||||||
|
@ -46,6 +59,8 @@ Description:
|
||||||
'platform'
|
'platform'
|
||||||
'shutdown'
|
'shutdown'
|
||||||
'reboot'
|
'reboot'
|
||||||
|
'testproc'
|
||||||
|
'test'
|
||||||
|
|
||||||
It will only change to 'firmware' or 'platform' if the system
|
It will only change to 'firmware' or 'platform' if the system
|
||||||
supports that.
|
supports that.
|
||||||
|
|
|
@ -30,6 +30,17 @@ testing). The system will support either 'firmware' or 'platform', and
|
||||||
that is known a priori. But, the user may choose 'shutdown' or
|
that is known a priori. But, the user may choose 'shutdown' or
|
||||||
'reboot' as alternatives.
|
'reboot' as alternatives.
|
||||||
|
|
||||||
|
Additionally, /sys/power/disk can be used to turn on one of the two testing
|
||||||
|
modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the
|
||||||
|
suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to
|
||||||
|
/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
|
||||||
|
tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is
|
||||||
|
in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel
|
||||||
|
to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
|
||||||
|
for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
|
||||||
|
we are able to look in the log messages and work out, for example, which code
|
||||||
|
is being slow and which device drivers are misbehaving.
|
||||||
|
|
||||||
Reading from this file will display what the mode is currently set
|
Reading from this file will display what the mode is currently set
|
||||||
to. Writing to this file will accept one of
|
to. Writing to this file will accept one of
|
||||||
|
|
||||||
|
@ -37,6 +48,8 @@ to. Writing to this file will accept one of
|
||||||
'platform'
|
'platform'
|
||||||
'shutdown'
|
'shutdown'
|
||||||
'reboot'
|
'reboot'
|
||||||
|
'testproc'
|
||||||
|
'test'
|
||||||
|
|
||||||
It will only change to 'firmware' or 'platform' if the system supports
|
It will only change to 'firmware' or 'platform' if the system supports
|
||||||
it.
|
it.
|
||||||
|
|
|
@ -116,7 +116,9 @@ typedef int __bitwise suspend_disk_method_t;
|
||||||
#define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2)
|
#define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2)
|
||||||
#define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3)
|
#define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3)
|
||||||
#define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4)
|
#define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4)
|
||||||
#define PM_DISK_MAX ((__force suspend_disk_method_t) 5)
|
#define PM_DISK_TEST ((__force suspend_disk_method_t) 5)
|
||||||
|
#define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6)
|
||||||
|
#define PM_DISK_MAX ((__force suspend_disk_method_t) 7)
|
||||||
|
|
||||||
struct pm_ops {
|
struct pm_ops {
|
||||||
suspend_disk_method_t pm_disk_mode;
|
suspend_disk_method_t pm_disk_mode;
|
||||||
|
|
|
@ -71,7 +71,7 @@ static inline void platform_finish(void)
|
||||||
|
|
||||||
static int prepare_processes(void)
|
static int prepare_processes(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error = 0;
|
||||||
|
|
||||||
pm_prepare_console();
|
pm_prepare_console();
|
||||||
|
|
||||||
|
@ -84,6 +84,12 @@ static int prepare_processes(void)
|
||||||
goto thaw;
|
goto thaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pm_disk_mode == PM_DISK_TESTPROC) {
|
||||||
|
printk("swsusp debug: Waiting for 5 seconds.\n");
|
||||||
|
mdelay(5000);
|
||||||
|
goto thaw;
|
||||||
|
}
|
||||||
|
|
||||||
/* Free memory before shutting down devices. */
|
/* Free memory before shutting down devices. */
|
||||||
if (!(error = swsusp_shrink_memory()))
|
if (!(error = swsusp_shrink_memory()))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -120,13 +126,21 @@ int pm_suspend_disk(void)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
if (pm_disk_mode == PM_DISK_TESTPROC)
|
||||||
|
goto Thaw;
|
||||||
|
|
||||||
suspend_console();
|
suspend_console();
|
||||||
error = device_suspend(PMSG_FREEZE);
|
error = device_suspend(PMSG_FREEZE);
|
||||||
if (error) {
|
if (error) {
|
||||||
resume_console();
|
resume_console();
|
||||||
printk("Some devices failed to suspend\n");
|
printk("Some devices failed to suspend\n");
|
||||||
unprepare_processes();
|
goto Thaw;
|
||||||
return error;
|
}
|
||||||
|
|
||||||
|
if (pm_disk_mode == PM_DISK_TEST) {
|
||||||
|
printk("swsusp debug: Waiting for 5 seconds.\n");
|
||||||
|
mdelay(5000);
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("PM: snapshotting memory.\n");
|
pr_debug("PM: snapshotting memory.\n");
|
||||||
|
@ -143,16 +157,17 @@ int pm_suspend_disk(void)
|
||||||
power_down(pm_disk_mode);
|
power_down(pm_disk_mode);
|
||||||
else {
|
else {
|
||||||
swsusp_free();
|
swsusp_free();
|
||||||
unprepare_processes();
|
goto Thaw;
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
pr_debug("PM: Image restored successfully.\n");
|
pr_debug("PM: Image restored successfully.\n");
|
||||||
|
}
|
||||||
|
|
||||||
swsusp_free();
|
swsusp_free();
|
||||||
Done:
|
Done:
|
||||||
device_resume();
|
device_resume();
|
||||||
resume_console();
|
resume_console();
|
||||||
|
Thaw:
|
||||||
unprepare_processes();
|
unprepare_processes();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -249,6 +264,8 @@ static const char * const pm_disk_modes[] = {
|
||||||
[PM_DISK_PLATFORM] = "platform",
|
[PM_DISK_PLATFORM] = "platform",
|
||||||
[PM_DISK_SHUTDOWN] = "shutdown",
|
[PM_DISK_SHUTDOWN] = "shutdown",
|
||||||
[PM_DISK_REBOOT] = "reboot",
|
[PM_DISK_REBOOT] = "reboot",
|
||||||
|
[PM_DISK_TEST] = "test",
|
||||||
|
[PM_DISK_TESTPROC] = "testproc",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -303,17 +320,19 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode) {
|
if (mode) {
|
||||||
if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
|
if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT ||
|
||||||
|
mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) {
|
||||||
pm_disk_mode = mode;
|
pm_disk_mode = mode;
|
||||||
else {
|
} else {
|
||||||
if (pm_ops && pm_ops->enter &&
|
if (pm_ops && pm_ops->enter &&
|
||||||
(mode == pm_ops->pm_disk_mode))
|
(mode == pm_ops->pm_disk_mode))
|
||||||
pm_disk_mode = mode;
|
pm_disk_mode = mode;
|
||||||
else
|
else
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
pr_debug("PM: suspend-to-disk mode set to '%s'\n",
|
pr_debug("PM: suspend-to-disk mode set to '%s'\n",
|
||||||
pm_disk_modes[mode]);
|
pm_disk_modes[mode]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue