Downloading & Installing PM-Graph
The tools can most easily be installed via git clone and make install
$> git clone http://github.com/intel/pm-graph.git
$> cd pm-graph
$> sudo make install
$> man sleepgraph
A snapshot of the tool is also found in the kernel source under tools/power/pm-graph. The pm-graph tools run with python2 or python3, the choice is made by the /usr/bin/python link. The tools should run in python3 out of the box on most systems, but for python2 you must install python-configparser.
Package Requirements:
- python (core execution)
- python-configparser (for python2)
- python-requests (for googlesheet tools)
- linux-tools-common (includes turbostat which sleepgraph uses in freeze)
$> sudo apt-get install python-configparser python-requests linux-tools-common
Configuring Your Linux Kernel
The kernel config is what determines which parts of the kernel are to be enabled when the kernel is built. In OS distros this config is usually placed in /boot/config-kversion. You will need to be sure that the following kernel config options are enabled for your kernel in order for the sleepgraph & bootgraph tools to work. If they're not, you will need to build a custom kernel and install it yourself.
Required: the tool uses the debug output from the PM subsystem to capture device timing.
- CONFIG_PM=y
- CONFIG_PM_DEBUG=y
- CONFIG_PM_SLEEP_DEBUG=y
- CONFIG_FTRACE=y
- CONFIG_FUNCTION_TRACER=y
- CONFIG_FUNCTION_GRAPH_TRACER=y
- CONFIG_KPROBES=y
- CONFIG_KPROBES_ON_FTRACE=y
- CONFIGURING KERNEL COMMAND LINE OPTIONS (V3.15 OR OLDER)
When the kernel is loaded, it pulls in a set of command line paramaters which allow for runtime configuration of the kernel: much like a user mode program. The parameters are stored in the boot loader config and must be configured using whatever boot loader your system has. The following kernel parameters are required for sleepgraph & bootgraph: initcall_debug and log_buf_len. initcall_debug is required so that the tool can know when devices are being initialized on boot, suspend, and resume. It's also a good idea to increase the size of the kernel log buffer because we don't want it to overflow.
For ubuntu/fedora: you can add these parameters at boot time in the grub menu by editting the /boot/grub/grub.cfg file, or by adding them to /etc/default/grub. The last method is the best because it will automatically edit the grub.cfg file for newly installed kernels.
/etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=16M ..."
For Android: These paramters must be set when you build the kernel. In your android source folder, edit the BoardConfig.mk file for the target build and add the new parameters:
nano device/<vendor>/<platform>/BoardConfig.mk
BOARD_KERNEL_CMDLINE += initcall_debug log_buf_len=16M
then build android and boot/install with live.img
source build/envsetup.sh
lunch <platform>-<build>
make -j8 allimages
dd if=out/target/product/<platform>/live.img of=/dev/sdc
Usage (Basic)
First configure a kernel using the instructions from the previous sections. Then build, install, and boot with it. Open up a terminal window and execute the mode list command:
%> sudo sleepgraph -modes
['freeze', 'mem', 'disk', 'mem-s2idle', 'disk-platform', 'disk-shutdown', 'disk-reboot', 'disk-suspend', 'disk-test_resume']
Now you can execute a test using one of the available power modes, e.g. mem (S3):
%> sudo sleepgraph -m mem -rtcwake 15
or with a config file
%> sudo sleepgraph -config config/suspend.cfg
When the system comes back you'll see the script finishing up and creating the output files in the test subdir. It generates output files in subdirectory: suspend-mmddyy-HHMMSS. The ftrace file can be used to regenerate the html timeline with different options.
HTML output | <hostname>_<mode>.html |
Kernel dmesg log | <hostname>_<mode>_dmesg.txt |
Kernel ftrace log | <hostname>_<mode>_ftrace.txt |
View the html in firefox or chrome. It will look like this:
Usage (Dev Mode)
Developer mode adds information on low level source calls to the timeline. The tool sets kprobes on all delay and mutex calls to see which devices are waiting for something and when. It also sets a suite of kprobes on subsystem dependant calls to better fill out the timeline.
The tool will also expose kernel threads that don't normally show up in the timeline. This is useful in discovering dependant threads to get a better idea of what each device is waiting for. For instance, the scsi_eh thread, a.k.a. scsi resume error handler, is what each SATA disk device waits for before it can continue resume.
The timeline will be much larger if run with dev mode, so it can be useful to set the -mindev option to clip out any device blocks that are too small to see easily. The following command will give a nice dev mode run:
%> sudo sleepgraph -m mem -rtcwake 15 -mindev 1 -dev
or with a config file
%> sudo sleepgraph -config config/suspend-dev.cfg
View the html in firefox or chrome. It will look like this:
Usage (Proc Mode)
Proc mode adds user process info to the timeline. This is done in a manner similar to the bootchart utility, which graphs init processes and their execution as the system boots. This tool option does the same thing but for the period before and after suspend/resume.
In order to see any process info, there needs to be some delay before or after resume since processes are frozen in suspend_prepare and thawed in resume_complete. The predelay and postdelay args allow you to do this. It can also be useful to run in x2 mode with an x2 delay, this way you can see process activity before and after resume, and in between two successive suspend/resumes.
The command is run like this:
%> sudo sleepgraph -m mem -rtcwake 15 -x2 -x2delay 1000 -predelay 1000 -postdelay 1000 -proc
or with a config file
%> sudo sleepgraph -config config/suspend-proc.cfg
View the html in firefox or chrome. It will look like this:
Basic Commands
Test Whether the Tool Can Execute (-Status)
The sleepgraph tool has several basic requirements which have to be met before it can do its job. For instance, when testing on linux you need root permission and the sysfs filesystem mounted. You also need ftrace to be configured properly and available in sysfs. So there's alot to verify, and the tool can do it for you. The status command will go through all the command line arguments and test whether or not you can run that particular command on the current platform. This can be helpful to help diagnose errors. For example here is the output of a command that the system supports:
%> sudo sleepgraph -status -m mem
Checking this system (ivybridge)...
have root access: YES
is sysfs mounted: YES
is "mem" a valid power mode: YES
is ftrace supported: YES
are kprobes supported: YES
timeline data source: FTRACE (all trace events found)
is rtcwake supported: YES
This is the output of a command with a missing requirement:
%> sudo sleepgraph -status -m standby
Checking this system (ivybridge)...
have root access: YES
is sysfs mounted: YES
is "standby" a valid power mode: NO
is ftrace supported: YES
are kprobes supported: YES
timeline data source: FTRACE (all trace events found)
is rtcwake supported: YES
View Supported Low-Power Modes (-Modes)
The tool was designed with S3 suspend/resume as its primary target, but it can run any power mode that the system allows you to enter via /sys/power/state. Nearly all systems support S3: "mem", and also hibernate: "disk". But there are also modes like "standby" and "freeze". Running this command lets you know what's available.
%> sleepgraph -modes
['freeze', 'mem', 'disk', 'mem-s2idle', 'disk-platform', 'disk-shutdown', 'disk-reboot', 'disk-suspend', 'disk-test_resume']
View Firmware Performance Data Table (-FPDT)
The ACPI subsystem in the kernel provides access to several tables populated with firmware data. There's one in particular called the Firmware Performance Data Table (FPDT) that the tool now makes use of. This table provides nanosecond level timing data on the last run suspend and resume initiated on the system. The tool first provides a new argument called -fpdt which causes the tool to read out the current table contents. This can be used to test if this feature is supported on your platform.
%> sudo sleepgraph -fpdt
Firmware Performance Data Table (FPDT)
Signature : FPDT
Table Length : 68
Revision : 1
Checksum : 0x84
OEM ID : INTEL
OEM Table ID : TIANO
OEM Revision : 1
Creator ID : MSFT
Creator Revision : 0x1000013
Firmware Basic Boot Performance Record (FBPT)
Reset END : 8836123 ns
OS Loader LoadImage Start : 0 ns
OS Loader StartImage Start : 10796773297 ns
ExitBootServices Entry : 0 ns
ExitBootServices Exit : 0 ns
S3 Performance Table Record (S3PT)
Basic S3 Resume Performance Record
Resume Count : 0
FullResume : 0 ns
AverageResume : 0 ns
Basic S3 Suspend Performance Record
SuspendStart : 0 ns
SuspendEnd : 0 ns
SuspendTime : 0 ns
The tool also makes use of this data during a test run and adds it into the timeline. If the FPDT data is available and valid, a new section will appear in the timeline named BIOS; along with two entries: firmware-suspend and firmware-resume. If the fpdt data isn't there then the timeline just displays the kernel data. NOTE: this does not yet function on android.
Recreate the HTML Output From a Previous Run's Log Data (-FTRACE)
The primary input to the tool is the ftrace output recorded during the suspend/resume. Ftrace logs that were generated by this tool have a few additional lines at the top & bottom which record basic test information about what, where, and when the test was run. Logs generated by this tool can be used to re-create exact copies of the html outputs. You just need to run the tool with the path of the ftrace log and the same arguments as the test run (-dev and -proc for instance).
%> sleepgraph -ftrace ivybridge_mem_ftrace.txt (-dev -f -proc)
or with a config
%> sleepgraph -ftrace ivybridge_mem_ftrace.txt -config myconfig.cfg
Tool Q&A
What is Sleepgraph?
The sleepgraph tool is a python script which gathers performance data from a system suspend and converts it into a device timeline and an optional callgraph. It is used to assist linux developers in optimizing and debuging their kernel's suspend/resume execution path.
How Can I Tell What Features and Arguments are Available?
The help text can be seen with sleepgraph -h, and there is a man page installed.
SleepGraph v5.5
Usage: sudo sleepgraph <options> <commands>
Description:
This tool is designed to assist kernel and OS developers in optimizing
their linux stack's suspend/resume time. Using a kernel image built
with a few extra options enabled, the tool will execute a suspend and
capture dmesg and ftrace data until resume is complete. This data is
transformed into a device timeline and an optional callgraph to give
a detailed view of which devices/subsystems are taking the most
time in suspend/resume.
If no specific command is given, the default behavior is to initiate
a suspend/resume and capture the dmesg/ftrace output as an html timeline.
Generates output files in subdirectory: suspend-yymmdd-HHMMSS
HTML output: <hostname>_<mode>.html
raw dmesg output: <hostname>_<mode>_dmesg.txt
raw ftrace output: <hostname>_<mode>_ftrace.txt
Options:
-h Print this help text
-v Print the current tool version
-config fn Pull arguments and config options from file fn
-verbose Print extra information during execution and analysis
-m mode Mode to initiate for suspend (default: mem)
-o name Overrides the output subdirectory name when running a new test
default: suspend-{date}-{time}
-rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)
-addlogs Add the dmesg and ftrace logs to the html output
-noturbostat Dont use turbostat in freeze mode (default: disabled)
-srgap Add a visible gap in the timeline between sus/res (default: disabled)
-skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)
-result fn Export a results table to a text file for parsing.
[testprep]
-sync Sync the filesystems before starting the test
-rs on/off Enable/disable runtime suspend for all devices, restore all after test
-display m Change the display mode to m for the test (on/off/standby/suspend)
[advanced]
-gzip Gzip the trace and dmesg logs to save space
-cmd {s} Run the timeline over a custom command, e.g. "sync -d"
-proc Add usermode process info into the timeline (default: disabled)
-dev Add kernel function calls and threads to the timeline (default: disabled)
-x2 Run two suspend/resumes back to back (default: disabled)
-x2delay t Include t ms delay between multiple test runs (default: 0 ms)
-predelay t Include t ms delay before 1st suspend (default: 0 ms)
-postdelay t Include t ms delay after last resume (default: 0 ms)
-mindev ms Discard all device blocks shorter than ms milliseconds (e.g. 0.001 for us)
-multi n d Execute <n> consecutive tests at <d> seconds intervals. The outputs will
be created in a new subdirectory with a summary page.
[debug]
-f Use ftrace to create device callgraphs (default: disabled)
-ftop Use ftrace on the top level call: "suspend_devices_and_enter" (default: disabled)
-maxdepth N limit the callgraph data to N call levels (default: 0=all)
-expandcg pre-expand the callgraph data in the html output (default: disabled)
-fadd file Add functions to be graphed in the timeline from a list in a text file
-filter "d1,d2,..." Filter out all but this comma-delimited list of device names
-mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)
-cgphase P Only show callgraph data for phase P (e.g. suspend_late)
-cgtest N Only show callgraph data for test N (e.g. 0 or 1 in an x2 run)
-timeprec N Number of significant digits in timestamps (0:S, [3:ms], 6:us)
-cgfilter S Filter the callgraph output in the timeline
-cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)
-bufsize N Set trace buffer size to N kilo-bytes (default: all of free memory)
-devdump Print out all the raw device data for each phase
-cgdump Print out all the raw callgraph data
Other commands:
-modes List available suspend modes
-status Test to see if the system is enabled to run this tool
-fpdt Print out the contents of the ACPI Firmware Performance Data Table
-battery Print out battery info (if available)
-wifi Print out wifi connection info (if wireless-tools and device exists)
-x<mode> Test xset by toggling the given mode (on/off/standby/suspend)
-sysinfo Print out system info extracted from BIOS
-devinfo Print out the pm settings of all devices which support runtime suspend
-flist Print the list of functions currently being captured in ftrace
-flistall Print all functions capable of being captured in ftrace
-summary dir Create a summary of tests in this dir [-genhtml builds missing html]
[redo]
-ftrace ftracefile Create HTML output using ftrace input (used with -dmesg)
-dmesg dmesgfile Create HTML output using dmesg (used with -ftrace)
How Does It Initiate the Suspend/Resume?
The tool interfaces with the kernel entirely using the /sys filesystem. The /sys/power/(state, mem_sleep, and disk) files can be read to determine what low power modes the kernel supports, and can be written to initiate those modes.
root$ cat /sys/power/state
standby freeze mem disk
root$ cat /sys/power/mem_sleep
s2idle [deep]
root$ cat /sys/power/disk
[platform] shutdown reboot suspend test_resume
The above outputs are converted into the following modes that sleepgraph supports:
root$ sleepgraph -modes
['freeze', 'mem', 'disk', 'mem-s2idle', 'disk-platform', 'disk-shutdown', 'disk-reboot', 'disk-suspend', 'disk-test_resume']
When you pass the above strings to "sleepgraph -m <mode>", the tool performs the following operations to enter the requested mode:
freeze
- echo freeze > /sys/power/state
mem
- echo deep > /sys/power/mem_sleep
- echo mem > /sys/power/state
mem-s2idle
- echo s2idle > /sys/power/mem_sleep
- echo mem > /sys/power/state
disk
- echo disk > /sys/power/state
disk-platform
- echo platform > /sys/power/disk
- echo disk > /sys/power/state
disk-shutdown
- echo shutdown > /sys/power/disk
- echo disk > /sys/power/state
disk-reboot
- echo reboot > /sys/power/disk
- echo disk > /sys/power/state
disk-platform
- echo platform > /sys/power/disk
- echo disk > /sys/power/state
disk-test_resume
- echo test_resume > /sys/power/disk
- echo disk > /sys/power/state
There are four ACPI power states that linux supports (not all of which may be supported on your system).
- standby: S1 (Power-On Suspend) - clock continues to run (delay shows in the timeline)
- freeze: S2idle (Low-Power Idle) - depends on BIOS settings, could be S3 or S2idle
- mem: S3 (suspend to RAM) - clock stops, the state is stored in RAM
- disk: S4 (suspend to disk) - clock stops, memory is flushed to disk, reboots with disk image
By default the system wakes up after 15 seconds, but you can use -rtcwake to change this number, or give it -rtcwake off to disable wakeups. In the "-rtcwake off" case the sytem stays suspended until a human interface device is touched (keypress, mouse, etc).
What Data Does It Gather During Suspend/Resume?
The ftrace log is the primary source of information. The kernel provides tracepoint data on all pm device callbacks, and the tool adds kprobes on other functions of interest in the timeline. When running with callgraph enabled it will also include ftrace callgraph data. The tool also grabs the dmesg log as it will contain any error messages and can help in debug.
Dev mode: The tool has a large suite of kprobes which it monitors in dev mode to add function info to the timeline. It primarily focuses on delay functions such as msleeps and schedule_timeouts and also any mutex_lock_slowpaths which occur when a device is waiting a long time for some other thread. The user can also define custom kprobes in the config file which will also be added to the ftrace log.
Proc mode: The tool gathers process data by polling the /proc/pid files in the proc filesystem. Every 5 ms or so it loops through them to determine which have executed any jiffies since the last poll, and uses that data to create the cpu usage graph and process blocks in the timeline. This data is actually fed into the ftrace subsystem via trace markers, since we want the proc data to have the same timestamps as the ftrace data. It will also be contained in the ftrace log.
How Does It Output the Data for Me to See?
The output of the tool is a single html file which includes HTML, CSS, and Javascript. It can be viewed in any linux browser without any js libraries or external dependencies. The device timeline is the primary feature of the page which shows all the device execution blocks. It uses javascript/CSS to allow zooming in and out and automatically changing the scale. On first load the timeline shows up fully expanded, and there are three buttons which can be used to zoom in and out, and a scrollbar to slide back and forth
- zoom-in (+ hotkey): decrease the time window and increase the timescale precision (down to individual milliseconds)
- zoom-out (- hotkey): increase the time window and decrease the timescale precision (up to several seconds)
- zoom-1:1(* hotkey): zoom back to the default 100% view
- slider: when in higher zoom levels the slider lets you move back and forth on the timeline
- grab & drag: the timeline can be grabbed and dragged left/right with the mouse
The timeline itself is also interactive. If you hover the pointer over a device it will highlight, and after a half second will display the full name of the device and the total time spent in its pm callback. You can also click the devices to get to a device detail view, which adds another section underneath the timeline. This view gives the full title of the device, it's total time spent, and also a hierarchy of all the devices parents, siblings, and children. If you have ftrace data enabled, clicking the device will also filter the callgraph data to show you just the device you clicked, its siblings, and children. This can be very helpful if you're optimizing a subsystem and need to understand the interaction between its devices.
NOTE: You may potentially run into some sluggishness when you view the output of an ftrace enabled test. This is because all the ftrace data needed to make callgraphs for dozens of devices can take up a lot of space, typically around 30MB. If your html file is over 100MB it may crash the browser, so you should rerun the test with the -filter option enabled to focus only on the devices you care about.
Project: pm-graph