3 pm-graph: suspend/resume/boot timing analysis tools
5 Author: Todd Brandt <todd.e.brandt@intel.com>
6 Home Page: https://01.org/pm-graph
8 Report bugs/issues at bugzilla.kernel.org Tools/pm-graph
9 - https://bugzilla.kernel.org/buglist.cgi?component=pm-graph&product=Tools
11 Full documentation available online & in man pages
13 https://01.org/pm-graph/documentation/getting-started
16 https://01.org/pm-graph/documentation/3-config-file-format
18 - upstream version in git:
19 https://github.com/intel/pm-graph/
31 - Custom Timeline Entries
32 - Adding/Editing Timeline Functions
33 - Adding/Editing Dev Timeline Source Functions
34 - Verifying your Custom Functions
35 - Testing on consumer linux Operating Systems
38 ------------------------------------------------------------------
40 ------------------------------------------------------------------
42 This tool suite is designed to assist kernel and OS developers in optimizing
43 their linux stack's suspend/resume & boot time. Using a kernel image built
44 with a few extra options enabled, the tools will execute a suspend or boot,
45 and will capture dmesg and ftrace data. This data is transformed into a set of
46 timelines and a callgraph to give a quick and detailed view of which devices
47 and kernel processes are taking the most time in suspend/resume & boot.
49 ------------------------------------------------------------------
51 ------------------------------------------------------------------
53 These packages are required to execute the scripts
58 sudo apt-get install python python-requests
61 sudo dnf install python python-requests
63 The tools can most easily be installed via git clone and make install
65 $> git clone http://github.com/intel/pm-graph.git
68 $> man sleepgraph ; man bootgraph
70 Setup involves some minor kernel configuration
72 The following kernel build options are required for all kernels:
75 CONFIG_PM_SLEEP_DEBUG=y
77 CONFIG_FUNCTION_TRACER=y
78 CONFIG_FUNCTION_GRAPH_TRACER=y
80 CONFIG_KPROBES_ON_FTRACE=y
82 In kernel 3.15.0, two patches were upstreamed which enable the
83 v3.0 behavior. These patches allow the tool to read all the
84 data from trace events instead of from dmesg. You can enable
85 this behavior on earlier kernels with these patches:
87 (kernel/pre-3.15/enable_trace_events_suspend_resume.patch)
88 (kernel/pre-3.15/enable_trace_events_device_pm_callback.patch)
90 If you're using a kernel older than 3.15.0, the following
91 additional kernel parameters are required:
92 (e.g. in file /etc/default/grub)
93 GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=32M ..."
95 If you're using a kernel older than 3.11-rc2, the following simple
96 patch must be applied to enable ftrace data:
97 in file: kernel/power/suspend.c
98 in function: int suspend_devices_and_enter(suspend_state_t state)
99 remove call to "ftrace_stop();"
100 remove call to "ftrace_start();"
102 There is a patch which does this for kernel v3.8.0:
103 (kernel/pre-3.11-rc2/enable_ftrace_in_suspendresume.patch)
107 ------------------------------------------------------------------
109 ------------------------------------------------------------------
114 1) First configure a kernel using the instructions from the previous sections.
115 Then build, install, and boot with it.
116 2) Open up a terminal window and execute the mode list command:
118 %> sudo ./sleepgraph.py -modes
119 ['freeze', 'mem', 'disk']
121 Execute a test using one of the available power modes, e.g. mem (S3):
123 %> sudo ./sleepgraph.py -m mem -rtcwake 15
125 or with a config file
127 %> sudo ./sleepgraph.py -config config/suspend.cfg
129 When the system comes back you'll see the script finishing up and
130 creating the output files in the test subdir. It generates output
131 files in subdirectory: suspend-mmddyy-HHMMSS. The ftrace file can
132 be used to regenerate the html timeline with different options
134 HTML output: <hostname>_<mode>.html
135 raw dmesg output: <hostname>_<mode>_dmesg.txt
136 raw ftrace output: <hostname>_<mode>_ftrace.txt
138 View the html in firefox or chrome.
144 Developer mode adds information on low level source calls to the timeline.
145 The tool sets kprobes on all delay and mutex calls to see which devices
146 are waiting for something and when. It also sets a suite of kprobes on
147 subsystem dependent calls to better fill out the timeline.
149 The tool will also expose kernel threads that don't normally show up in the
150 timeline. This is useful in discovering dependent threads to get a better
151 idea of what each device is waiting for. For instance, the scsi_eh thread,
152 a.k.a. scsi resume error handler, is what each SATA disk device waits for
153 before it can continue resume.
155 The timeline will be much larger if run with dev mode, so it can be useful
156 to set the -mindev option to clip out any device blocks that are too small
157 to see easily. The following command will give a nice dev mode run:
159 %> sudo ./sleepgraph.py -m mem -rtcwake 15 -mindev 1 -dev
161 or with a config file
163 %> sudo ./sleepgraph.py -config config/suspend-dev.cfg
169 Proc mode adds user process info to the timeline. This is done in a manner
170 similar to the bootchart utility, which graphs init processes and their
171 execution as the system boots. This tool option does the same thing but for
172 the period before and after suspend/resume.
174 In order to see any process info, there needs to be some delay before or
175 after resume since processes are frozen in suspend_prepare and thawed in
176 resume_complete. The predelay and postdelay args allow you to do this. It
177 can also be useful to run in x2 mode with an x2 delay, this way you can
178 see process activity before and after resume, and in between two
179 successive suspend/resumes.
181 The command can be run like this:
183 %> sudo ./sleepgraph.py -m mem -rtcwake 15 -x2 -x2delay 1000 -predelay 1000 -postdelay 1000 -proc
185 or with a config file
187 %> sudo ./sleepgraph.py -config config/suspend-proc.cfg
190 ------------------------------------------------------------------
191 | CONFIGURATION FILES |
192 ------------------------------------------------------------------
194 Since 4.0 we've moved to using config files in lieu of command line options.
195 The config folder contains a collection of typical use cases.
196 There are corresponding configs for other power modes:
198 Simple suspend/resume with basic timeline (mem/freeze/standby)
203 Dev mode suspend/resume with dev timeline (mem/freeze/standby)
204 config/suspend-dev.cfg
205 config/freeze-dev.cfg
206 config/standby-dev.cfg
208 Simple suspend/resume with timeline and callgraph (mem/freeze/standby)
209 config/suspend-callgraph.cfg
210 config/freeze-callgraph.cfg
211 config/standby-callgraph.cfg
213 Sample proc mode x2 run using mem suspend
214 config/suspend-x2-proc.cfg
216 Sample for editing timeline funcs (moves internal functions into config)
217 config/custom-timeline-functions.cfg
219 Sample debug config for serio subsystem
220 config/debug-serio-suspend.cfg
226 Run a simple mem suspend:
227 %> sudo ./sleepgraph.py -config config/suspend.cfg
229 Run a mem suspend with callgraph data:
230 %> sudo ./sleepgraph.py -config config/suspend-callgraph.cfg
232 Run a mem suspend with dev mode detail:
233 %> sudo ./sleepgraph.py -config config/suspend-dev.cfg
241 # Verbosity: print verbose messages (def: false)
244 # Suspend Mode: e.g. standby, mem, freeze, disk (def: mem)
247 # Output Directory Format: {hostname}, {date}, {time} give current values
248 output-dir: suspend-{hostname}-{date}-{time}
250 # Automatic Wakeup: use rtcwake to wakeup after X seconds (def: infinity)
253 # Add Logs: add the dmesg and ftrace log to the html output (def: false)
256 # Sus/Res Gap: insert a gap between sus & res in the timeline (def: false)
259 # Custom Command: Command to execute in lieu of suspend (def: "")
260 command: echo mem > /sys/power/state
262 # Proc mode: graph user processes and cpu usage in the timeline (def: false)
265 # Dev mode: graph source functions in the timeline (def: false)
268 # Suspend/Resume x2: run 2 suspend/resumes back to back (def: false)
271 # x2 Suspend Delay: time delay between the two test runs in ms (def: 0 ms)
274 # Pre Suspend Delay: nclude an N ms delay before (1st) suspend (def: 0 ms)
277 # Post Resume Delay: include an N ms delay after (last) resume (def: 0 ms)
280 # Min Device Length: graph only dev callbacks longer than min (def: 0.001 ms)
283 # Callgraph: gather ftrace callgraph data on all timeline events (def: false)
286 # Expand Callgraph: pre-expand the callgraph treeviews in html (def: false)
289 # Min Callgraph Length: show callgraphs only if longer than min (def: 1 ms)
292 # Timestamp Precision: number of sig digits in timestamps (0:S, [3:ms], 6:us)
295 # Device Filter: show only devs whose name/driver includes one of these strings
296 devicefilter: _cpu_up,_cpu_down,i915,usb
298 # Override default timeline entries:
299 # Do not use the internal default functions for timeline entries (def: false)
300 # Set this to true if you intend to only use the ones defined in the config
301 override-timeline-functions: true
303 # Override default dev timeline entries:
304 # Do not use the internal default functions for dev timeline entries (def: false)
305 # Set this to true if you intend to only use the ones defined in the config
306 override-dev-timeline-functions: true
308 # Call Loop Max Gap (dev mode only)
309 # merge loops of the same call if each is less than maxgap apart (def: 100us)
310 callloop-maxgap: 0.0001
312 # Call Loop Max Length (dev mode only)
313 # merge loops of the same call if each is less than maxlen in length (def: 5ms)
314 callloop-maxlen: 0.005
316 ------------------------------------------------------------------
317 | CUSTOM TIMELINE ENTRIES |
318 ------------------------------------------------------------------
320 Adding or Editing Timeline Functions
321 ____________________________________
323 The tool uses an array of function names to fill out empty spaces in the
324 timeline where device callbacks don't appear. For instance, in suspend_prepare
325 the tool adds the sys_sync and freeze_processes calls as virtual device blocks
326 in the timeline to show you where the time is going. These calls should fill
327 the timeline with contiguous data so that most kernel execution is covered.
329 It is possible to add new function calls to the timeline by adding them to
330 the config. It's also possible to copy the internal timeline functions into
331 the config so that you can override and edit them. Place them in the
332 timeline_functions_ARCH section with the name of your architecture appended.
333 i.e. for x86_64: [timeline_functions_x86_64]
335 Use the override-timeline-functions option if you only want to use your
336 custom calls, or leave it false to append them to the internal ones.
338 This section includes a list of functions (set using kprobes) which use both
339 symbol data and function arg data. The args are pulled directly from the
340 stack using this architecture's registers and stack formatting. Each entry
341 can include up to four pieces of info: The function name, a format string,
342 an argument list, and a color. But only a function name is required.
344 For a full example config, see config/custom-timeline-functions.cfg. It pulls
345 all the internal timeline functions into the config and allows you to edit
350 function: format{fn_arg1}_{fn_arg2} fn_arg1 fn_arg2 ... [color=purple]
354 function: The symbol name for the function you want probed, this is the
355 minimum required for an entry, it will show up as the function
356 name with no arguments.
362 format: The format to display the data on the timeline in. Use braces to
363 enclose the arg names.
365 example: CPU_ON[{cpu}]
367 color: The color of the entry block in the timeline. The default color is
368 transparent, so the entry shares the phase color. The color is an
369 html color string, either a word, or an RGB.
371 example: [color=#CC00CC]
373 arglist: A list of arguments from registers/stack addresses. See URL:
374 https://www.kernel.org/doc/Documentation/trace/kprobetrace.txt
378 Here is a full example entry. It displays cpu resume calls in the timeline
379 in orange. They will appear as CPU_ON[0], CPU_ON[1], etc.
381 [timeline_functions_x86_64]
382 _cpu_up: CPU_ON[{cpu}] cpu=%di:s32 [color=orange]
385 Adding or Editing Dev Mode Timeline Source Functions
386 ____________________________________________________
388 In dev mode, the tool uses an array of function names to monitor source
389 execution within the timeline entries.
391 The function calls are displayed inside the main device/call blocks in the
392 timeline. However, if a function call is not within a main timeline event,
393 it will spawn an entirely new event named after the caller's kernel thread.
394 These asynchronous kernel threads will populate in a separate section
395 beneath the main device/call section.
397 The tool has a set of hard coded calls which focus on the most common use
398 cases: msleep, udelay, schedule_timeout, mutex_lock_slowpath, etc. These are
399 the functions that add a hardcoded time delay to the suspend/resume path.
400 The tool also includes some common functions native to important
401 subsystems: ata, i915, and ACPI, etc.
403 It is possible to add new function calls to the dev timeline by adding them
404 to the config. It's also possible to copy the internal dev timeline
405 functions into the config so that you can override and edit them. Place them
406 in the dev_timeline_functions_ARCH section with the name of your architecture
407 appended. i.e. for x86_64: [dev_timeline_functions_x86_64]
409 Use the override-dev-timeline-functions option if you only want to use your
410 custom calls, or leave it false to append them to the internal ones.
412 The format is the same as the timeline_functions_x86_64 section. It's a
413 list of functions (set using kprobes) which use both symbol data and function
414 arg data. The args are pulled directly from the stack using this
415 architecture's registers and stack formatting. Each entry can include up
416 to four pieces of info: The function name, a format string, an argument list,
417 and a color. But only the function name is required.
419 For a full example config, see config/custom-timeline-functions.cfg. It pulls
420 all the internal dev timeline functions into the config and allows you to edit
423 Here is a full example entry. It displays the ATA port reset calls as
424 ataN_port_reset in the timeline. This is where most of the SATA disk resume
425 time goes, so it can be helpful to see the low level call.
427 [dev_timeline_functions_x86_64]
428 ata_eh_recover: ata{port}_port_reset port=+36(%di):s32 [color=#CC00CC]
431 Verifying your custom functions
432 _______________________________
434 Once you have a set of functions (kprobes) defined, it can be useful to
435 perform a quick check to see if you formatted them correctly and if the system
436 actually supports them. To do this, run the tool with your config file
437 and the -status option. The tool will go through all the kprobes (both
438 custom and internal if you haven't overridden them) and actually attempts
439 to set them in ftrace. It will then print out success or fail for you.
441 Note that kprobes which don't actually exist in the kernel won't stop the
442 tool, they just wont show up.
446 sudo ./sleepgraph.py -config config/custom-timeline-functions.cfg -status
447 Checking this system (myhostname)...
448 have root access: YES
449 is sysfs mounted: YES
450 is "mem" a valid power mode: YES
451 is ftrace supported: YES
452 are kprobes supported: YES
453 timeline data source: FTRACE (all trace events found)
454 is rtcwake supported: YES
455 verifying timeline kprobes work:
460 freeze_kernel_threads: YES
461 freeze_processes: YES
464 verifying dev kprobes work:
466 __mutex_lock_slowpath: YES
468 acpi_ps_parse_aml: YES
469 intel_opregion_init: NO
470 intel_opregion_register: NO
471 intel_opregion_setup: NO
473 schedule_timeout: YES
474 schedule_timeout_uninterruptible: YES
478 ------------------------------------------------------------------
479 | TESTING ON CONSUMER LINUX OPERATING SYSTEMS |
480 ------------------------------------------------------------------
485 The easiest way to execute on an android device is to run the android.sh
486 script on the device, then pull the ftrace log back to the host and run
491 [download and install the tool on the device]
493 host%> wget https://raw.githubusercontent.com/intel/pm-graph/master/tools/android.sh
494 host%> adb connect 192.168.1.6
496 # push the script to a writeable location
497 host%> adb push android.sh /sdcard/
499 [check whether the tool will run on your device]
503 dev%> sh android.sh status
505 kernel : 3.14.0-i386-dirty
510 suspend_resume: found
511 device_pm_callback_end: found
512 device_pm_callback_start: found
514 # the above is what you see on a system that's properly patched
516 [execute the suspend]
518 # NOTE: The suspend will only work if the screen isn't timed out,
519 # so you have to press some keys first to wake it up b4 suspend)
520 dev%> sh android.sh suspend mem
521 ------------------------------------
522 Suspend/Resume timing test initiated
523 ------------------------------------
525 kernel : 3.14.0-i386-dirty
527 ftrace out : /mnt/shell/emulated/0/ftrace.txt
528 dmesg out : /mnt/shell/emulated/0/dmesg.txt
529 log file : /mnt/shell/emulated/0/log.txt
530 ------------------------------------
531 INITIALIZING FTRACE........DONE
533 SUSPEND START @ 21:24:02 (rtcwake in 10 seconds)
534 <adb connection will now terminate>
536 [retrieve the data from the device]
538 # I find that you have to actually kill the adb process and
539 # reconnect sometimes in order for the connection to work post-suspend
540 host%> adb connect 192.168.1.6
541 # (required) get the ftrace data, this is the most important piece
542 host%> adb pull /sdcard/ftrace.txt
543 # (optional) get the dmesg data, this is for debugging
544 host%> adb pull /sdcard/dmesg.txt
545 # (optional) get the log, which just lists some test times for comparison
546 host%> adb pull /sdcard/log.txt
548 [create an output html file using sleepgraph.py]
550 host%> sleepgraph.py -ftrace ftrace.txt
552 You should now have an output.html with the android data, enjoy!