PM / sleep: add configurable delay for pm_test

When CONFIG_PM_DEBUG=y, we provide a sysfs file (/sys/power/pm_test) for
selecting one of a few suspend test modes, where rather than entering a
full suspend state, the kernel will perform some subset of suspend
steps, wait 5 seconds, and then resume back to normal operation.

This mode is useful for (among other things) observing the state of the
system just before entering a sleep mode, for debugging or analysis
purposes. However, a constant 5 second wait is not sufficient for some
sorts of analysis; for example, on an SoC, one might want to use
external tools to probe the power states of various on-chip controllers
or clocks.

This patch turns this 5 second delay into a configurable module
parameter, so users can determine how long to wait in this
pseudo-suspend state before resuming the system.

Example (wait 30 seconds);

  # echo 30 > /sys/module/suspend/parameters/pm_test_delay
  # echo core > /sys/power/pm_test
  # time echo mem  > /sys/power/state
  ...
  [   17.583625] suspend debug: Waiting for 30 second(s).
  ...
  real	0m30.381s
  user	0m0.017s
  sys	0m0.080s

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Kevin Cernekee <cernekee@chromium.org>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Brian Norris 2015-02-22 21:16:49 -08:00 committed by Rafael J. Wysocki
parent c517d838eb
commit 1d4a9c17d4
3 changed files with 24 additions and 6 deletions

View file

@ -3462,6 +3462,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
improve throughput, but will also increase the improve throughput, but will also increase the
amount of memory reserved for use by the client. amount of memory reserved for use by the client.
suspend.pm_test_delay=
[SUSPEND]
Sets the number of seconds to remain in a suspend test
mode before resuming the system (see
/sys/power/pm_test). Only available when CONFIG_PM_DEBUG
is set. Default value is 5.
swapaccount=[0|1] swapaccount=[0|1]
[KNL] Enable accounting of swap in memory resource [KNL] Enable accounting of swap in memory resource
controller if no parameter or 1 is given or disable controller if no parameter or 1 is given or disable

View file

@ -75,12 +75,14 @@ you should do the following:
# echo platform > /sys/power/disk # echo platform > /sys/power/disk
# echo disk > /sys/power/state # echo disk > /sys/power/state
Then, the kernel will try to freeze processes, suspend devices, wait 5 seconds, Then, the kernel will try to freeze processes, suspend devices, wait a few
resume devices and thaw processes. If "platform" is written to seconds (5 by default, but configurable by the suspend.pm_test_delay module
parameter), resume devices and thaw processes. If "platform" is written to
/sys/power/pm_test , then after suspending devices the kernel will additionally /sys/power/pm_test , then after suspending devices the kernel will additionally
invoke the global control methods (eg. ACPI global control methods) used to invoke the global control methods (eg. ACPI global control methods) used to
prepare the platform firmware for hibernation. Next, it will wait 5 seconds and prepare the platform firmware for hibernation. Next, it will wait a
invoke the platform (eg. ACPI) global methods used to cancel hibernation etc. configurable number of seconds and invoke the platform (eg. ACPI) global
methods used to cancel hibernation etc.
Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal
hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test

View file

@ -28,6 +28,7 @@
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <trace/events/power.h> #include <trace/events/power.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/moduleparam.h>
#include "power.h" #include "power.h"
@ -233,12 +234,20 @@ static bool platform_suspend_again(suspend_state_t state)
suspend_ops->suspend_again() : false; suspend_ops->suspend_again() : false;
} }
#ifdef CONFIG_PM_DEBUG
static unsigned int pm_test_delay = 5;
module_param(pm_test_delay, uint, 0644);
MODULE_PARM_DESC(pm_test_delay,
"Number of seconds to wait before resuming from suspend test");
#endif
static int suspend_test(int level) static int suspend_test(int level)
{ {
#ifdef CONFIG_PM_DEBUG #ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) { if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); printk(KERN_INFO "suspend debug: Waiting for %d second(s).\n",
mdelay(5000); pm_test_delay);
mdelay(pm_test_delay * 1000);
return 1; return 1;
} }
#endif /* !CONFIG_PM_DEBUG */ #endif /* !CONFIG_PM_DEBUG */