1 p m - g r a p h 2 3 pm-graph: suspend/resume/boot timing analysis tools 4 Version: 5.5 5 Author: Todd Brandt <todd.e.brandt@intel.com> 6 Home Page: https://01.org/pm-graph 7 8 Report bugs/issues at bugzilla.kernel.org Tools/pm-graph 9 - https://bugzilla.kernel.org/buglist.cgi?component=pm-graph&product=Tools 10 11 Full documentation available online & in man pages 12 - Getting Started: 13 https://01.org/pm-graph/documentation/getting-started 14 15 - Config File Format: 16 https://01.org/pm-graph/documentation/3-config-file-format 17 18 - upstream version in git: 19 https://github.com/intel/pm-graph/ 20 21 Requirements: 22 - runs with python2 or python3, choice is made by /usr/bin/python link 23 - python2 now requires python-configparser be installed 24 25 Table of Contents 26 - Overview 27 - Setup 28 - Usage 29 - Basic Usage 30 - Dev Mode Usage 31 - Proc Mode Usage 32 - Configuration Files 33 - Usage Examples 34 - Config File Options 35 - Custom Timeline Entries 36 - Adding/Editing Timeline Functions 37 - Adding/Editing Dev Timeline Source Functions 38 - Verifying your Custom Functions 39 - Testing on consumer linux Operating Systems 40 - Android 41 42------------------------------------------------------------------ 43| OVERVIEW | 44------------------------------------------------------------------ 45 46 This tool suite is designed to assist kernel and OS developers in optimizing 47 their linux stack's suspend/resume & boot time. Using a kernel image built 48 with a few extra options enabled, the tools will execute a suspend or boot, 49 and will capture dmesg and ftrace data. This data is transformed into a set of 50 timelines and a callgraph to give a quick and detailed view of which devices 51 and kernel processes are taking the most time in suspend/resume & boot. 52 53------------------------------------------------------------------ 54| SETUP | 55------------------------------------------------------------------ 56 57 These packages are required to execute the scripts 58 - python 59 - python-requests 60 61 Ubuntu: 62 sudo apt-get install python python-requests 63 64 Fedora: 65 sudo dnf install python python-requests 66 67 The tools can most easily be installed via git clone and make install 68 69 $> git clone http://github.com/intel/pm-graph.git 70 $> cd pm-graph 71 $> sudo make install 72 $> man sleepgraph ; man bootgraph 73 74 Setup involves some minor kernel configuration 75 76 The following kernel build options are required for all kernels: 77 CONFIG_DEVMEM=y 78 CONFIG_PM_DEBUG=y 79 CONFIG_PM_SLEEP_DEBUG=y 80 CONFIG_FTRACE=y 81 CONFIG_FUNCTION_TRACER=y 82 CONFIG_FUNCTION_GRAPH_TRACER=y 83 CONFIG_KPROBES=y 84 CONFIG_KPROBES_ON_FTRACE=y 85 86 In kernel 3.15.0, two patches were upstreamed which enable the 87 v3.0 behavior. These patches allow the tool to read all the 88 data from trace events instead of from dmesg. You can enable 89 this behavior on earlier kernels with these patches: 90 91 (kernel/pre-3.15/enable_trace_events_suspend_resume.patch) 92 (kernel/pre-3.15/enable_trace_events_device_pm_callback.patch) 93 94 If you're using a kernel older than 3.15.0, the following 95 additional kernel parameters are required: 96 (e.g. in file /etc/default/grub) 97 GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=32M ..." 98 99 If you're using a kernel older than 3.11-rc2, the following simple 100 patch must be applied to enable ftrace data: 101 in file: kernel/power/suspend.c 102 in function: int suspend_devices_and_enter(suspend_state_t state) 103 remove call to "ftrace_stop();" 104 remove call to "ftrace_start();" 105 106 There is a patch which does this for kernel v3.8.0: 107 (kernel/pre-3.11-rc2/enable_ftrace_in_suspendresume.patch) 108 109 110 111------------------------------------------------------------------ 112| USAGE | 113------------------------------------------------------------------ 114 115Basic Usage 116___________ 117 118 1) First configure a kernel using the instructions from the previous sections. 119 Then build, install, and boot with it. 120 2) Open up a terminal window and execute the mode list command: 121 122 %> sudo ./sleepgraph.py -modes 123 ['freeze', 'mem', 'disk'] 124 125 Execute a test using one of the available power modes, e.g. mem (S3): 126 127 %> sudo ./sleepgraph.py -m mem -rtcwake 15 128 129 or with a config file 130 131 %> sudo ./sleepgraph.py -config config/suspend.cfg 132 133 When the system comes back you'll see the script finishing up and 134 creating the output files in the test subdir. It generates output 135 files in subdirectory: suspend-mmddyy-HHMMSS. The ftrace file can 136 be used to regenerate the html timeline with different options 137 138 HTML output: <hostname>_<mode>.html 139 raw dmesg output: <hostname>_<mode>_dmesg.txt 140 raw ftrace output: <hostname>_<mode>_ftrace.txt 141 142 View the html in firefox or chrome. 143 144 145Dev Mode Usage 146______________ 147 148 Developer mode adds information on low level source calls to the timeline. 149 The tool sets kprobes on all delay and mutex calls to see which devices 150 are waiting for something and when. It also sets a suite of kprobes on 151 subsystem dependent calls to better fill out the timeline. 152 153 The tool will also expose kernel threads that don't normally show up in the 154 timeline. This is useful in discovering dependent threads to get a better 155 idea of what each device is waiting for. For instance, the scsi_eh thread, 156 a.k.a. scsi resume error handler, is what each SATA disk device waits for 157 before it can continue resume. 158 159 The timeline will be much larger if run with dev mode, so it can be useful 160 to set the -mindev option to clip out any device blocks that are too small 161 to see easily. The following command will give a nice dev mode run: 162 163 %> sudo ./sleepgraph.py -m mem -rtcwake 15 -mindev 1 -dev 164 165 or with a config file 166 167 %> sudo ./sleepgraph.py -config config/suspend-dev.cfg 168 169 170Proc Mode Usage 171_______________ 172 173 Proc mode adds user process info to the timeline. This is done in a manner 174 similar to the bootchart utility, which graphs init processes and their 175 execution as the system boots. This tool option does the same thing but for 176 the period before and after suspend/resume. 177 178 In order to see any process info, there needs to be some delay before or 179 after resume since processes are frozen in suspend_prepare and thawed in 180 resume_complete. The predelay and postdelay args allow you to do this. It 181 can also be useful to run in x2 mode with an x2 delay, this way you can 182 see process activity before and after resume, and in between two 183 successive suspend/resumes. 184 185 The command can be run like this: 186 187 %> sudo ./sleepgraph.py -m mem -rtcwake 15 -x2 -x2delay 1000 -predelay 1000 -postdelay 1000 -proc 188 189 or with a config file 190 191 %> sudo ./sleepgraph.py -config config/suspend-proc.cfg 192 193 194------------------------------------------------------------------ 195| CONFIGURATION FILES | 196------------------------------------------------------------------ 197 198 Since 4.0 we've moved to using config files in lieu of command line options. 199 The config folder contains a collection of typical use cases. 200 There are corresponding configs for other power modes: 201 202 Simple suspend/resume with basic timeline (mem/freeze/standby) 203 config/suspend.cfg 204 config/freeze.cfg 205 config/standby.cfg 206 207 Dev mode suspend/resume with dev timeline (mem/freeze/standby) 208 config/suspend-dev.cfg 209 config/freeze-dev.cfg 210 config/standby-dev.cfg 211 212 Simple suspend/resume with timeline and callgraph (mem/freeze/standby) 213 config/suspend-callgraph.cfg 214 config/freeze-callgraph.cfg 215 config/standby-callgraph.cfg 216 217 Sample proc mode x2 run using mem suspend 218 config/suspend-x2-proc.cfg 219 220 Sample for editing timeline funcs (moves internal functions into config) 221 config/custom-timeline-functions.cfg 222 223 Sample debug config for serio subsystem 224 config/debug-serio-suspend.cfg 225 226 227Usage Examples 228______________ 229 230 Run a simple mem suspend: 231 %> sudo ./sleepgraph.py -config config/suspend.cfg 232 233 Run a mem suspend with callgraph data: 234 %> sudo ./sleepgraph.py -config config/suspend-callgraph.cfg 235 236 Run a mem suspend with dev mode detail: 237 %> sudo ./sleepgraph.py -config config/suspend-dev.cfg 238 239 240Config File Options 241___________________ 242 243 [Settings] 244 245 # Verbosity: print verbose messages (def: false) 246 verbose: false 247 248 # Suspend Mode: e.g. standby, mem, freeze, disk (def: mem) 249 mode: mem 250 251 # Output Directory Format: {hostname}, {date}, {time} give current values 252 output-dir: suspend-{hostname}-{date}-{time} 253 254 # Automatic Wakeup: use rtcwake to wakeup after X seconds (def: infinity) 255 rtcwake: 15 256 257 # Add Logs: add the dmesg and ftrace log to the html output (def: false) 258 addlogs: false 259 260 # Sus/Res Gap: insert a gap between sus & res in the timeline (def: false) 261 srgap: false 262 263 # Custom Command: Command to execute in lieu of suspend (def: "") 264 command: echo mem > /sys/power/state 265 266 # Proc mode: graph user processes and cpu usage in the timeline (def: false) 267 proc: false 268 269 # Dev mode: graph source functions in the timeline (def: false) 270 dev: false 271 272 # Suspend/Resume x2: run 2 suspend/resumes back to back (def: false) 273 x2: false 274 275 # x2 Suspend Delay: time delay between the two test runs in ms (def: 0 ms) 276 x2delay: 0 277 278 # Pre Suspend Delay: nclude an N ms delay before (1st) suspend (def: 0 ms) 279 predelay: 0 280 281 # Post Resume Delay: include an N ms delay after (last) resume (def: 0 ms) 282 postdelay: 0 283 284 # Min Device Length: graph only dev callbacks longer than min (def: 0.001 ms) 285 mindev: 0.001 286 287 # Callgraph: gather ftrace callgraph data on all timeline events (def: false) 288 callgraph: false 289 290 # Expand Callgraph: pre-expand the callgraph treeviews in html (def: false) 291 expandcg: false 292 293 # Min Callgraph Length: show callgraphs only if longer than min (def: 1 ms) 294 mincg: 1 295 296 # Timestamp Precision: number of sig digits in timestamps (0:S, [3:ms], 6:us) 297 timeprec: 3 298 299 # Device Filter: show only devs whose name/driver includes one of these strings 300 devicefilter: _cpu_up,_cpu_down,i915,usb 301 302 # Override default timeline entries: 303 # Do not use the internal default functions for timeline entries (def: false) 304 # Set this to true if you intend to only use the ones defined in the config 305 override-timeline-functions: true 306 307 # Override default dev timeline entries: 308 # Do not use the internal default functions for dev timeline entries (def: false) 309 # Set this to true if you intend to only use the ones defined in the config 310 override-dev-timeline-functions: true 311 312 # Call Loop Max Gap (dev mode only) 313 # merge loops of the same call if each is less than maxgap apart (def: 100us) 314 callloop-maxgap: 0.0001 315 316 # Call Loop Max Length (dev mode only) 317 # merge loops of the same call if each is less than maxlen in length (def: 5ms) 318 callloop-maxlen: 0.005 319 320------------------------------------------------------------------ 321| CUSTOM TIMELINE ENTRIES | 322------------------------------------------------------------------ 323 324Adding or Editing Timeline Functions 325____________________________________ 326 327 The tool uses an array of function names to fill out empty spaces in the 328 timeline where device callbacks don't appear. For instance, in suspend_prepare 329 the tool adds the sys_sync and freeze_processes calls as virtual device blocks 330 in the timeline to show you where the time is going. These calls should fill 331 the timeline with contiguous data so that most kernel execution is covered. 332 333 It is possible to add new function calls to the timeline by adding them to 334 the config. It's also possible to copy the internal timeline functions into 335 the config so that you can override and edit them. Place them in the 336 timeline_functions_ARCH section with the name of your architecture appended. 337 i.e. for x86_64: [timeline_functions_x86_64] 338 339 Use the override-timeline-functions option if you only want to use your 340 custom calls, or leave it false to append them to the internal ones. 341 342 This section includes a list of functions (set using kprobes) which use both 343 symbol data and function arg data. The args are pulled directly from the 344 stack using this architecture's registers and stack formatting. Each entry 345 can include up to four pieces of info: The function name, a format string, 346 an argument list, and a color. But only a function name is required. 347 348 For a full example config, see config/custom-timeline-functions.cfg. It pulls 349 all the internal timeline functions into the config and allows you to edit 350 them. 351 352 Entry format: 353 354 function: format{fn_arg1}_{fn_arg2} fn_arg1 fn_arg2 ... [color=purple] 355 356 Required Arguments: 357 358 function: The symbol name for the function you want probed, this is the 359 minimum required for an entry, it will show up as the function 360 name with no arguments. 361 362 example: _cpu_up: 363 364 Optional Arguments: 365 366 format: The format to display the data on the timeline in. Use braces to 367 enclose the arg names. 368 369 example: CPU_ON[{cpu}] 370 371 color: The color of the entry block in the timeline. The default color is 372 transparent, so the entry shares the phase color. The color is an 373 html color string, either a word, or an RGB. 374 375 example: [color=#CC00CC] 376 377 arglist: A list of arguments from registers/stack addresses. See URL: 378 https://www.kernel.org/doc/Documentation/trace/kprobetrace.txt 379 380 example: cpu=%di:s32 381 382 Here is a full example entry. It displays cpu resume calls in the timeline 383 in orange. They will appear as CPU_ON[0], CPU_ON[1], etc. 384 385 [timeline_functions_x86_64] 386 _cpu_up: CPU_ON[{cpu}] cpu=%di:s32 [color=orange] 387 388 389Adding or Editing Dev Mode Timeline Source Functions 390____________________________________________________ 391 392 In dev mode, the tool uses an array of function names to monitor source 393 execution within the timeline entries. 394 395 The function calls are displayed inside the main device/call blocks in the 396 timeline. However, if a function call is not within a main timeline event, 397 it will spawn an entirely new event named after the caller's kernel thread. 398 These asynchronous kernel threads will populate in a separate section 399 beneath the main device/call section. 400 401 The tool has a set of hard coded calls which focus on the most common use 402 cases: msleep, udelay, schedule_timeout, mutex_lock_slowpath, etc. These are 403 the functions that add a hardcoded time delay to the suspend/resume path. 404 The tool also includes some common functions native to important 405 subsystems: ata, i915, and ACPI, etc. 406 407 It is possible to add new function calls to the dev timeline by adding them 408 to the config. It's also possible to copy the internal dev timeline 409 functions into the config so that you can override and edit them. Place them 410 in the dev_timeline_functions_ARCH section with the name of your architecture 411 appended. i.e. for x86_64: [dev_timeline_functions_x86_64] 412 413 Use the override-dev-timeline-functions option if you only want to use your 414 custom calls, or leave it false to append them to the internal ones. 415 416 The format is the same as the timeline_functions_x86_64 section. It's a 417 list of functions (set using kprobes) which use both symbol data and function 418 arg data. The args are pulled directly from the stack using this 419 architecture's registers and stack formatting. Each entry can include up 420 to four pieces of info: The function name, a format string, an argument list, 421 and a color. But only the function name is required. 422 423 For a full example config, see config/custom-timeline-functions.cfg. It pulls 424 all the internal dev timeline functions into the config and allows you to edit 425 them. 426 427 Here is a full example entry. It displays the ATA port reset calls as 428 ataN_port_reset in the timeline. This is where most of the SATA disk resume 429 time goes, so it can be helpful to see the low level call. 430 431 [dev_timeline_functions_x86_64] 432 ata_eh_recover: ata{port}_port_reset port=+36(%di):s32 [color=#CC00CC] 433 434 435Verifying your custom functions 436_______________________________ 437 438 Once you have a set of functions (kprobes) defined, it can be useful to 439 perform a quick check to see if you formatted them correctly and if the system 440 actually supports them. To do this, run the tool with your config file 441 and the -status option. The tool will go through all the kprobes (both 442 custom and internal if you haven't overridden them) and actually attempts 443 to set them in ftrace. It will then print out success or fail for you. 444 445 Note that kprobes which don't actually exist in the kernel won't stop the 446 tool, they just wont show up. 447 448 For example: 449 450 sudo ./sleepgraph.py -config config/custom-timeline-functions.cfg -status 451 Checking this system (myhostname)... 452 have root access: YES 453 is sysfs mounted: YES 454 is "mem" a valid power mode: YES 455 is ftrace supported: YES 456 are kprobes supported: YES 457 timeline data source: FTRACE (all trace events found) 458 is rtcwake supported: YES 459 verifying timeline kprobes work: 460 _cpu_down: YES 461 _cpu_up: YES 462 acpi_pm_finish: YES 463 acpi_pm_prepare: YES 464 freeze_kernel_threads: YES 465 freeze_processes: YES 466 sys_sync: YES 467 thaw_processes: YES 468 verifying dev kprobes work: 469 __const_udelay: YES 470 __mutex_lock_slowpath: YES 471 acpi_os_stall: YES 472 acpi_ps_parse_aml: YES 473 intel_opregion_init: NO 474 intel_opregion_register: NO 475 intel_opregion_setup: NO 476 msleep: YES 477 schedule_timeout: YES 478 schedule_timeout_uninterruptible: YES 479 usleep_range: YES 480 481 482------------------------------------------------------------------ 483| TESTING ON CONSUMER LINUX OPERATING SYSTEMS | 484------------------------------------------------------------------ 485 486Android 487_______ 488 489 The easiest way to execute on an android device is to run the android.sh 490 script on the device, then pull the ftrace log back to the host and run 491 sleepgraph.py on it. 492 493 Here are the steps: 494 495 [download and install the tool on the device] 496 497 host%> wget https://raw.githubusercontent.com/intel/pm-graph/master/tools/android.sh 498 host%> adb connect 192.168.1.6 499 host%> adb root 500 # push the script to a writeable location 501 host%> adb push android.sh /sdcard/ 502 503 [check whether the tool will run on your device] 504 505 host%> adb shell 506 dev%> cd /sdcard 507 dev%> sh android.sh status 508 host : asus_t100 509 kernel : 3.14.0-i386-dirty 510 modes : freeze mem 511 rtcwake : supported 512 ftrace : supported 513 trace events { 514 suspend_resume: found 515 device_pm_callback_end: found 516 device_pm_callback_start: found 517 } 518 # the above is what you see on a system that's properly patched 519 520 [execute the suspend] 521 522 # NOTE: The suspend will only work if the screen isn't timed out, 523 # so you have to press some keys first to wake it up b4 suspend) 524 dev%> sh android.sh suspend mem 525 ------------------------------------ 526 Suspend/Resume timing test initiated 527 ------------------------------------ 528 hostname : asus_t100 529 kernel : 3.14.0-i386-dirty 530 mode : mem 531 ftrace out : /mnt/shell/emulated/0/ftrace.txt 532 dmesg out : /mnt/shell/emulated/0/dmesg.txt 533 log file : /mnt/shell/emulated/0/log.txt 534 ------------------------------------ 535 INITIALIZING FTRACE........DONE 536 STARTING FTRACE 537 SUSPEND START @ 21:24:02 (rtcwake in 10 seconds) 538 <adb connection will now terminate> 539 540 [retrieve the data from the device] 541 542 # I find that you have to actually kill the adb process and 543 # reconnect sometimes in order for the connection to work post-suspend 544 host%> adb connect 192.168.1.6 545 # (required) get the ftrace data, this is the most important piece 546 host%> adb pull /sdcard/ftrace.txt 547 # (optional) get the dmesg data, this is for debugging 548 host%> adb pull /sdcard/dmesg.txt 549 # (optional) get the log, which just lists some test times for comparison 550 host%> adb pull /sdcard/log.txt 551 552 [create an output html file using sleepgraph.py] 553 554 host%> sleepgraph.py -ftrace ftrace.txt 555 556 You should now have an output.html with the android data, enjoy! 557