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