162306a36Sopenharmony_ciperf-script-python(1)
262306a36Sopenharmony_ci====================
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciNAME
562306a36Sopenharmony_ci----
662306a36Sopenharmony_ciperf-script-python - Process trace data with a Python script
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciSYNOPSIS
962306a36Sopenharmony_ci--------
1062306a36Sopenharmony_ci[verse]
1162306a36Sopenharmony_ci'perf script' [-s [Python]:script[.py] ]
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciDESCRIPTION
1462306a36Sopenharmony_ci-----------
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciThis perf script option is used to process perf script data using perf's
1762306a36Sopenharmony_cibuilt-in Python interpreter.  It reads and processes the input file and
1862306a36Sopenharmony_cidisplays the results of the trace analysis implemented in the given
1962306a36Sopenharmony_ciPython script, if any.
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciA QUICK EXAMPLE
2262306a36Sopenharmony_ci---------------
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciThis section shows the process, start to finish, of creating a working
2562306a36Sopenharmony_ciPython script that aggregates and extracts useful information from a
2662306a36Sopenharmony_ciraw perf script stream.  You can avoid reading the rest of this
2762306a36Sopenharmony_cidocument if an example is enough for you; the rest of the document
2862306a36Sopenharmony_ciprovides more details on each step and lists the library functions
2962306a36Sopenharmony_ciavailable to script writers.
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciThis example actually details the steps that were used to create the
3262306a36Sopenharmony_ci'syscall-counts' script you see when you list the available perf script
3362306a36Sopenharmony_ciscripts via 'perf script -l'.  As such, this script also shows how to
3462306a36Sopenharmony_ciintegrate your script into the list of general-purpose 'perf script'
3562306a36Sopenharmony_ciscripts listed by that command.
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciThe syscall-counts script is a simple script, but demonstrates all the
3862306a36Sopenharmony_cibasic ideas necessary to create a useful script.  Here's an example
3962306a36Sopenharmony_ciof its output (syscall names are not yet supported, they will appear
4062306a36Sopenharmony_cias numbers):
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci----
4362306a36Sopenharmony_cisyscall events:
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cievent                                          count
4662306a36Sopenharmony_ci----------------------------------------  -----------
4762306a36Sopenharmony_cisys_write                                     455067
4862306a36Sopenharmony_cisys_getdents                                    4072
4962306a36Sopenharmony_cisys_close                                       3037
5062306a36Sopenharmony_cisys_swapoff                                     1769
5162306a36Sopenharmony_cisys_read                                         923
5262306a36Sopenharmony_cisys_sched_setparam                               826
5362306a36Sopenharmony_cisys_open                                         331
5462306a36Sopenharmony_cisys_newfstat                                     326
5562306a36Sopenharmony_cisys_mmap                                         217
5662306a36Sopenharmony_cisys_munmap                                       216
5762306a36Sopenharmony_cisys_futex                                        141
5862306a36Sopenharmony_cisys_select                                       102
5962306a36Sopenharmony_cisys_poll                                          84
6062306a36Sopenharmony_cisys_setitimer                                     12
6162306a36Sopenharmony_cisys_writev                                         8
6262306a36Sopenharmony_ci15                                                 8
6362306a36Sopenharmony_cisys_lseek                                          7
6462306a36Sopenharmony_cisys_rt_sigprocmask                                 6
6562306a36Sopenharmony_cisys_wait4                                          3
6662306a36Sopenharmony_cisys_ioctl                                          3
6762306a36Sopenharmony_cisys_set_robust_list                                1
6862306a36Sopenharmony_cisys_exit                                           1
6962306a36Sopenharmony_ci56                                                 1
7062306a36Sopenharmony_cisys_access                                         1
7162306a36Sopenharmony_ci----
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciBasically our task is to keep a per-syscall tally that gets updated
7462306a36Sopenharmony_cievery time a system call occurs in the system.  Our script will do
7562306a36Sopenharmony_cithat, but first we need to record the data that will be processed by
7662306a36Sopenharmony_cithat script.  Theoretically, there are a couple of ways we could do
7762306a36Sopenharmony_cithat:
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci- we could enable every event under the tracing/events/syscalls
8062306a36Sopenharmony_ci  directory, but this is over 600 syscalls, well beyond the number
8162306a36Sopenharmony_ci  allowable by perf.  These individual syscall events will however be
8262306a36Sopenharmony_ci  useful if we want to later use the guidance we get from the
8362306a36Sopenharmony_ci  general-purpose scripts to drill down and get more detail about
8462306a36Sopenharmony_ci  individual syscalls of interest.
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci- we can enable the sys_enter and/or sys_exit syscalls found under
8762306a36Sopenharmony_ci  tracing/events/raw_syscalls.  These are called for all syscalls; the
8862306a36Sopenharmony_ci  'id' field can be used to distinguish between individual syscall
8962306a36Sopenharmony_ci  numbers.
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciFor this script, we only need to know that a syscall was entered; we
9262306a36Sopenharmony_cidon't care how it exited, so we'll use 'perf record' to record only
9362306a36Sopenharmony_cithe sys_enter events:
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci----
9662306a36Sopenharmony_ci# perf record -a -e raw_syscalls:sys_enter
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci^C[ perf record: Woken up 1 times to write data ]
9962306a36Sopenharmony_ci[ perf record: Captured and wrote 56.545 MB perf.data (~2470503 samples) ]
10062306a36Sopenharmony_ci----
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciThe options basically say to collect data for every syscall event
10362306a36Sopenharmony_cisystem-wide and multiplex the per-cpu output into a single stream.
10462306a36Sopenharmony_ciThat single stream will be recorded in a file in the current directory
10562306a36Sopenharmony_cicalled perf.data.
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciOnce we have a perf.data file containing our data, we can use the -g
10862306a36Sopenharmony_ci'perf script' option to generate a Python script that will contain a
10962306a36Sopenharmony_cicallback handler for each event type found in the perf.data trace
11062306a36Sopenharmony_cistream (for more details, see the STARTER SCRIPTS section).
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci----
11362306a36Sopenharmony_ci# perf script -g python
11462306a36Sopenharmony_cigenerated Python script: perf-script.py
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciThe output file created also in the current directory is named
11762306a36Sopenharmony_ciperf-script.py.  Here's the file in its entirety:
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci# perf script event handlers, generated by perf script -g python
12062306a36Sopenharmony_ci# Licensed under the terms of the GNU GPL License version 2
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci# The common_* event handler fields are the most useful fields common to
12362306a36Sopenharmony_ci# all events.  They don't necessarily correspond to the 'common_*' fields
12462306a36Sopenharmony_ci# in the format files.  Those fields not available as handler params can
12562306a36Sopenharmony_ci# be retrieved using Python functions of the form common_*(context).
12662306a36Sopenharmony_ci# See the perf-script-python Documentation for the list of available functions.
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ciimport os
12962306a36Sopenharmony_ciimport sys
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cisys.path.append(os.environ['PERF_EXEC_PATH'] + \
13262306a36Sopenharmony_ci	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cifrom perf_trace_context import *
13562306a36Sopenharmony_cifrom Core import *
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cidef trace_begin():
13862306a36Sopenharmony_ci	print "in trace_begin"
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cidef trace_end():
14162306a36Sopenharmony_ci	print "in trace_end"
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cidef raw_syscalls__sys_enter(event_name, context, common_cpu,
14462306a36Sopenharmony_ci	common_secs, common_nsecs, common_pid, common_comm,
14562306a36Sopenharmony_ci	id, args):
14662306a36Sopenharmony_ci		print_header(event_name, common_cpu, common_secs, common_nsecs,
14762306a36Sopenharmony_ci			common_pid, common_comm)
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci		print "id=%d, args=%s\n" % \
15062306a36Sopenharmony_ci		(id, args),
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cidef trace_unhandled(event_name, context, event_fields_dict):
15362306a36Sopenharmony_ci		print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cidef print_header(event_name, cpu, secs, nsecs, pid, comm):
15662306a36Sopenharmony_ci	print "%-20s %5u %05u.%09u %8u %-20s " % \
15762306a36Sopenharmony_ci	(event_name, cpu, secs, nsecs, pid, comm),
15862306a36Sopenharmony_ci----
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ciAt the top is a comment block followed by some import statements and a
16162306a36Sopenharmony_cipath append which every perf script script should include.
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ciFollowing that are a couple generated functions, trace_begin() and
16462306a36Sopenharmony_citrace_end(), which are called at the beginning and the end of the
16562306a36Sopenharmony_ciscript respectively (for more details, see the SCRIPT_LAYOUT section
16662306a36Sopenharmony_cibelow).
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ciFollowing those are the 'event handler' functions generated one for
16962306a36Sopenharmony_cievery event in the 'perf record' output.  The handler functions take
17062306a36Sopenharmony_cithe form subsystem\__event_name, and contain named parameters, one for
17162306a36Sopenharmony_cieach field in the event; in this case, there's only one event,
17262306a36Sopenharmony_ciraw_syscalls__sys_enter().  (see the EVENT HANDLERS section below for
17362306a36Sopenharmony_cimore info on event handlers).
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ciThe final couple of functions are, like the begin and end functions,
17662306a36Sopenharmony_cigenerated for every script.  The first, trace_unhandled(), is called
17762306a36Sopenharmony_cievery time the script finds an event in the perf.data file that
17862306a36Sopenharmony_cidoesn't correspond to any event handler in the script.  This could
17962306a36Sopenharmony_cimean either that the record step recorded event types that it wasn't
18062306a36Sopenharmony_cireally interested in, or the script was run against a trace file that
18162306a36Sopenharmony_cidoesn't correspond to the script.
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ciThe script generated by -g option simply prints a line for each
18462306a36Sopenharmony_cievent found in the trace stream i.e. it basically just dumps the event
18562306a36Sopenharmony_ciand its parameter values to stdout.  The print_header() function is
18662306a36Sopenharmony_cisimply a utility function used for that purpose.  Let's rename the
18762306a36Sopenharmony_ciscript and run it to see the default output:
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci----
19062306a36Sopenharmony_ci# mv perf-script.py syscall-counts.py
19162306a36Sopenharmony_ci# perf script -s syscall-counts.py
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847582083     7506 perf                  id=1, args=
19462306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847595764     7506 perf                  id=1, args=
19562306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847620860     7506 perf                  id=1, args=
19662306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847710478     6533 npviewer.bin          id=78, args=
19762306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847719204     6533 npviewer.bin          id=142, args=
19862306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847755445     6533 npviewer.bin          id=3, args=
19962306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847775601     6533 npviewer.bin          id=3, args=
20062306a36Sopenharmony_ciraw_syscalls__sys_enter     1 00840.847781820     6533 npviewer.bin          id=3, args=
20162306a36Sopenharmony_ci.
20262306a36Sopenharmony_ci.
20362306a36Sopenharmony_ci.
20462306a36Sopenharmony_ci----
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciOf course, for this script, we're not interested in printing every
20762306a36Sopenharmony_citrace event, but rather aggregating it in a useful way.  So we'll get
20862306a36Sopenharmony_cirid of everything to do with printing as well as the trace_begin() and
20962306a36Sopenharmony_citrace_unhandled() functions, which we won't be using.  That leaves us
21062306a36Sopenharmony_ciwith this minimalistic skeleton:
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci----
21362306a36Sopenharmony_ciimport os
21462306a36Sopenharmony_ciimport sys
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cisys.path.append(os.environ['PERF_EXEC_PATH'] + \
21762306a36Sopenharmony_ci	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cifrom perf_trace_context import *
22062306a36Sopenharmony_cifrom Core import *
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cidef trace_end():
22362306a36Sopenharmony_ci	print "in trace_end"
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cidef raw_syscalls__sys_enter(event_name, context, common_cpu,
22662306a36Sopenharmony_ci	common_secs, common_nsecs, common_pid, common_comm,
22762306a36Sopenharmony_ci	id, args):
22862306a36Sopenharmony_ci----
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ciIn trace_end(), we'll simply print the results, but first we need to
23162306a36Sopenharmony_cigenerate some results to print.  To do that we need to have our
23262306a36Sopenharmony_cisys_enter() handler do the necessary tallying until all events have
23362306a36Sopenharmony_cibeen counted.  A hash table indexed by syscall id is a good way to
23462306a36Sopenharmony_cistore that information; every time the sys_enter() handler is called,
23562306a36Sopenharmony_ciwe simply increment a count associated with that hash entry indexed by
23662306a36Sopenharmony_cithat syscall id:
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci----
23962306a36Sopenharmony_ci  syscalls = autodict()
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci  try:
24262306a36Sopenharmony_ci    syscalls[id] += 1
24362306a36Sopenharmony_ci  except TypeError:
24462306a36Sopenharmony_ci    syscalls[id] = 1
24562306a36Sopenharmony_ci----
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ciThe syscalls 'autodict' object is a special kind of Python dictionary
24862306a36Sopenharmony_ci(implemented in Core.py) that implements Perl's 'autovivifying' hashes
24962306a36Sopenharmony_ciin Python i.e. with autovivifying hashes, you can assign nested hash
25062306a36Sopenharmony_civalues without having to go to the trouble of creating intermediate
25162306a36Sopenharmony_cilevels if they don't exist e.g syscalls[comm][pid][id] = 1 will create
25262306a36Sopenharmony_cithe intermediate hash levels and finally assign the value 1 to the
25362306a36Sopenharmony_cihash entry for 'id' (because the value being assigned isn't a hash
25462306a36Sopenharmony_ciobject itself, the initial value is assigned in the TypeError
25562306a36Sopenharmony_ciexception.  Well, there may be a better way to do this in Python but
25662306a36Sopenharmony_cithat's what works for now).
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ciPutting that code into the raw_syscalls__sys_enter() handler, we
25962306a36Sopenharmony_cieffectively end up with a single-level dictionary keyed on syscall id
26062306a36Sopenharmony_ciand having the counts we've tallied as values.
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ciThe print_syscall_totals() function iterates over the entries in the
26362306a36Sopenharmony_cidictionary and displays a line for each entry containing the syscall
26462306a36Sopenharmony_ciname (the dictionary keys contain the syscall ids, which are passed to
26562306a36Sopenharmony_cithe Util function syscall_name(), which translates the raw syscall
26662306a36Sopenharmony_cinumbers to the corresponding syscall name strings).  The output is
26762306a36Sopenharmony_cidisplayed after all the events in the trace have been processed, by
26862306a36Sopenharmony_cicalling the print_syscall_totals() function from the trace_end()
26962306a36Sopenharmony_cihandler called at the end of script processing.
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ciThe final script producing the output shown above is shown in its
27262306a36Sopenharmony_cientirety below (syscall_name() helper is not yet available, you can
27362306a36Sopenharmony_cionly deal with id's for now):
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci----
27662306a36Sopenharmony_ciimport os
27762306a36Sopenharmony_ciimport sys
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cisys.path.append(os.environ['PERF_EXEC_PATH'] + \
28062306a36Sopenharmony_ci	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cifrom perf_trace_context import *
28362306a36Sopenharmony_cifrom Core import *
28462306a36Sopenharmony_cifrom Util import *
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_cisyscalls = autodict()
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_cidef trace_end():
28962306a36Sopenharmony_ci	print_syscall_totals()
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cidef raw_syscalls__sys_enter(event_name, context, common_cpu,
29262306a36Sopenharmony_ci	common_secs, common_nsecs, common_pid, common_comm,
29362306a36Sopenharmony_ci	id, args):
29462306a36Sopenharmony_ci	try:
29562306a36Sopenharmony_ci		syscalls[id] += 1
29662306a36Sopenharmony_ci	except TypeError:
29762306a36Sopenharmony_ci		syscalls[id] = 1
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cidef print_syscall_totals():
30062306a36Sopenharmony_ci    if for_comm is not None:
30162306a36Sopenharmony_ci	    print "\nsyscall events for %s:\n\n" % (for_comm),
30262306a36Sopenharmony_ci    else:
30362306a36Sopenharmony_ci	    print "\nsyscall events:\n\n",
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci    print "%-40s  %10s\n" % ("event", "count"),
30662306a36Sopenharmony_ci    print "%-40s  %10s\n" % ("----------------------------------------", \
30762306a36Sopenharmony_ci                                 "-----------"),
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci    for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
31062306a36Sopenharmony_ci				  reverse = True):
31162306a36Sopenharmony_ci	    print "%-40s  %10d\n" % (syscall_name(id), val),
31262306a36Sopenharmony_ci----
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ciThe script can be run just as before:
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci  # perf script -s syscall-counts.py
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ciSo those are the essential steps in writing and running a script.  The
31962306a36Sopenharmony_ciprocess can be generalized to any tracepoint or set of tracepoints
32062306a36Sopenharmony_ciyou're interested in - basically find the tracepoint(s) you're
32162306a36Sopenharmony_ciinterested in by looking at the list of available events shown by
32262306a36Sopenharmony_ci'perf list' and/or look in /sys/kernel/tracing/events/ for
32362306a36Sopenharmony_cidetailed event and field info, record the corresponding trace data
32462306a36Sopenharmony_ciusing 'perf record', passing it the list of interesting events,
32562306a36Sopenharmony_cigenerate a skeleton script using 'perf script -g python' and modify the
32662306a36Sopenharmony_cicode to aggregate and display it for your particular needs.
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ciAfter you've done that you may end up with a general-purpose script
32962306a36Sopenharmony_cithat you want to keep around and have available for future use.  By
33062306a36Sopenharmony_ciwriting a couple of very simple shell scripts and putting them in the
33162306a36Sopenharmony_ciright place, you can have your script listed alongside the other
33262306a36Sopenharmony_ciscripts listed by the 'perf script -l' command e.g.:
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci----
33562306a36Sopenharmony_ci# perf script -l
33662306a36Sopenharmony_ciList of available trace scripts:
33762306a36Sopenharmony_ci  wakeup-latency                       system-wide min/max/avg wakeup latency
33862306a36Sopenharmony_ci  rw-by-file <comm>                    r/w activity for a program, by file
33962306a36Sopenharmony_ci  rw-by-pid                            system-wide r/w activity
34062306a36Sopenharmony_ci----
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ciA nice side effect of doing this is that you also then capture the
34362306a36Sopenharmony_ciprobably lengthy 'perf record' command needed to record the events for
34462306a36Sopenharmony_cithe script.
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ciTo have the script appear as a 'built-in' script, you write two simple
34762306a36Sopenharmony_ciscripts, one for recording and one for 'reporting'.
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ciThe 'record' script is a shell script with the same base name as your
35062306a36Sopenharmony_ciscript, but with -record appended.  The shell script should be put
35162306a36Sopenharmony_ciinto the perf/scripts/python/bin directory in the kernel source tree.
35262306a36Sopenharmony_ciIn that script, you write the 'perf record' command-line needed for
35362306a36Sopenharmony_ciyour script:
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci----
35662306a36Sopenharmony_ci# cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-record
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci#!/bin/bash
35962306a36Sopenharmony_ciperf record -a -e raw_syscalls:sys_enter
36062306a36Sopenharmony_ci----
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ciThe 'report' script is also a shell script with the same base name as
36362306a36Sopenharmony_ciyour script, but with -report appended.  It should also be located in
36462306a36Sopenharmony_cithe perf/scripts/python/bin directory.  In that script, you write the
36562306a36Sopenharmony_ci'perf script -s' command-line needed for running your script:
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci----
36862306a36Sopenharmony_ci# cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-report
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#!/bin/bash
37162306a36Sopenharmony_ci# description: system-wide syscall counts
37262306a36Sopenharmony_ciperf script -s ~/libexec/perf-core/scripts/python/syscall-counts.py
37362306a36Sopenharmony_ci----
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ciNote that the location of the Python script given in the shell script
37662306a36Sopenharmony_ciis in the libexec/perf-core/scripts/python directory - this is where
37762306a36Sopenharmony_cithe script will be copied by 'make install' when you install perf.
37862306a36Sopenharmony_ciFor the installation to install your script there, your script needs
37962306a36Sopenharmony_cito be located in the perf/scripts/python directory in the kernel
38062306a36Sopenharmony_cisource tree:
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci----
38362306a36Sopenharmony_ci# ls -al kernel-source/tools/perf/scripts/python
38462306a36Sopenharmony_citotal 32
38562306a36Sopenharmony_cidrwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
38662306a36Sopenharmony_cidrwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
38762306a36Sopenharmony_cidrwxr-xr-x 2 trz trz 4096 2010-01-26 22:29 bin
38862306a36Sopenharmony_ci-rw-r--r-- 1 trz trz 2548 2010-01-26 22:29 check-perf-script.py
38962306a36Sopenharmony_cidrwxr-xr-x 3 trz trz 4096 2010-01-26 22:49 Perf-Trace-Util
39062306a36Sopenharmony_ci-rw-r--r-- 1 trz trz 1462 2010-01-26 22:30 syscall-counts.py
39162306a36Sopenharmony_ci----
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciOnce you've done that (don't forget to do a new 'make install',
39462306a36Sopenharmony_ciotherwise your script won't show up at run-time), 'perf script -l'
39562306a36Sopenharmony_cishould show a new entry for your script:
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci----
39862306a36Sopenharmony_ci# perf script -l
39962306a36Sopenharmony_ciList of available trace scripts:
40062306a36Sopenharmony_ci  wakeup-latency                       system-wide min/max/avg wakeup latency
40162306a36Sopenharmony_ci  rw-by-file <comm>                    r/w activity for a program, by file
40262306a36Sopenharmony_ci  rw-by-pid                            system-wide r/w activity
40362306a36Sopenharmony_ci  syscall-counts                       system-wide syscall counts
40462306a36Sopenharmony_ci----
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ciYou can now perform the record step via 'perf script record':
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci  # perf script record syscall-counts
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ciand display the output using 'perf script report':
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci  # perf script report syscall-counts
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ciSTARTER SCRIPTS
41562306a36Sopenharmony_ci---------------
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ciYou can quickly get started writing a script for a particular set of
41862306a36Sopenharmony_citrace data by generating a skeleton script using 'perf script -g
41962306a36Sopenharmony_cipython' in the same directory as an existing perf.data trace file.
42062306a36Sopenharmony_ciThat will generate a starter script containing a handler for each of
42162306a36Sopenharmony_cithe event types in the trace file; it simply prints every available
42262306a36Sopenharmony_cifield for each event in the trace file.
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ciYou can also look at the existing scripts in
42562306a36Sopenharmony_ci~/libexec/perf-core/scripts/python for typical examples showing how to
42662306a36Sopenharmony_cido basic things like aggregate event data, print results, etc.  Also,
42762306a36Sopenharmony_cithe check-perf-script.py script, while not interesting for its results,
42862306a36Sopenharmony_ciattempts to exercise all of the main scripting features.
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ciEVENT HANDLERS
43162306a36Sopenharmony_ci--------------
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ciWhen perf script is invoked using a trace script, a user-defined
43462306a36Sopenharmony_ci'handler function' is called for each event in the trace.  If there's
43562306a36Sopenharmony_cino handler function defined for a given event type, the event is
43662306a36Sopenharmony_ciignored (or passed to a 'trace_unhandled' function, see below) and the
43762306a36Sopenharmony_cinext event is processed.
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ciMost of the event's field values are passed as arguments to the
44062306a36Sopenharmony_cihandler function; some of the less common ones aren't - those are
44162306a36Sopenharmony_ciavailable as calls back into the perf executable (see below).
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ciAs an example, the following perf record command can be used to record
44462306a36Sopenharmony_ciall sched_wakeup events in the system:
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci # perf record -a -e sched:sched_wakeup
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ciTraces meant to be processed using a script should be recorded with
44962306a36Sopenharmony_cithe above option: -a to enable system-wide collection.
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ciThe format file for the sched_wakeup event defines the following fields
45262306a36Sopenharmony_ci(see /sys/kernel/tracing/events/sched/sched_wakeup/format):
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci----
45562306a36Sopenharmony_ci format:
45662306a36Sopenharmony_ci        field:unsigned short common_type;
45762306a36Sopenharmony_ci        field:unsigned char common_flags;
45862306a36Sopenharmony_ci        field:unsigned char common_preempt_count;
45962306a36Sopenharmony_ci        field:int common_pid;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci        field:char comm[TASK_COMM_LEN];
46262306a36Sopenharmony_ci        field:pid_t pid;
46362306a36Sopenharmony_ci        field:int prio;
46462306a36Sopenharmony_ci        field:int success;
46562306a36Sopenharmony_ci        field:int target_cpu;
46662306a36Sopenharmony_ci----
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ciThe handler function for this event would be defined as:
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci----
47162306a36Sopenharmony_cidef sched__sched_wakeup(event_name, context, common_cpu, common_secs,
47262306a36Sopenharmony_ci       common_nsecs, common_pid, common_comm,
47362306a36Sopenharmony_ci       comm, pid, prio, success, target_cpu):
47462306a36Sopenharmony_ci       pass
47562306a36Sopenharmony_ci----
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ciThe handler function takes the form subsystem__event_name.
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ciThe common_* arguments in the handler's argument list are the set of
48062306a36Sopenharmony_ciarguments passed to all event handlers; some of the fields correspond
48162306a36Sopenharmony_cito the common_* fields in the format file, but some are synthesized,
48262306a36Sopenharmony_ciand some of the common_* fields aren't common enough to to be passed
48362306a36Sopenharmony_cito every event as arguments but are available as library functions.
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ciHere's a brief description of each of the invariant event args:
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci event_name 	  	    the name of the event as text
48862306a36Sopenharmony_ci context		    an opaque 'cookie' used in calls back into perf
48962306a36Sopenharmony_ci common_cpu		    the cpu the event occurred on
49062306a36Sopenharmony_ci common_secs		    the secs portion of the event timestamp
49162306a36Sopenharmony_ci common_nsecs		    the nsecs portion of the event timestamp
49262306a36Sopenharmony_ci common_pid		    the pid of the current task
49362306a36Sopenharmony_ci common_comm		    the name of the current process
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ciAll of the remaining fields in the event's format file have
49662306a36Sopenharmony_cicounterparts as handler function arguments of the same name, as can be
49762306a36Sopenharmony_ciseen in the example above.
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ciThe above provides the basics needed to directly access every field of
50062306a36Sopenharmony_cievery event in a trace, which covers 90% of what you need to know to
50162306a36Sopenharmony_ciwrite a useful trace script.  The sections below cover the rest.
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ciSCRIPT LAYOUT
50462306a36Sopenharmony_ci-------------
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ciEvery perf script Python script should start by setting up a Python
50762306a36Sopenharmony_cimodule search path and 'import'ing a few support modules (see module
50862306a36Sopenharmony_cidescriptions below):
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci----
51162306a36Sopenharmony_ci import os
51262306a36Sopenharmony_ci import sys
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci sys.path.append(os.environ['PERF_EXEC_PATH'] + \
51562306a36Sopenharmony_ci	      '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci from perf_trace_context import *
51862306a36Sopenharmony_ci from Core import *
51962306a36Sopenharmony_ci----
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ciThe rest of the script can contain handler functions and support
52262306a36Sopenharmony_cifunctions in any order.
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ciAside from the event handler functions discussed above, every script
52562306a36Sopenharmony_cican implement a set of optional functions:
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci*trace_begin*, if defined, is called before any event is processed and
52862306a36Sopenharmony_cigives scripts a chance to do setup tasks:
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci----
53162306a36Sopenharmony_cidef trace_begin():
53262306a36Sopenharmony_ci    pass
53362306a36Sopenharmony_ci----
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci*trace_end*, if defined, is called after all events have been
53662306a36Sopenharmony_ci processed and gives scripts a chance to do end-of-script tasks, such
53762306a36Sopenharmony_ci as display results:
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci----
54062306a36Sopenharmony_cidef trace_end():
54162306a36Sopenharmony_ci    pass
54262306a36Sopenharmony_ci----
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci*trace_unhandled*, if defined, is called after for any event that
54562306a36Sopenharmony_ci doesn't have a handler explicitly defined for it.  The standard set
54662306a36Sopenharmony_ci of common arguments are passed into it:
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci----
54962306a36Sopenharmony_cidef trace_unhandled(event_name, context, event_fields_dict):
55062306a36Sopenharmony_ci    pass
55162306a36Sopenharmony_ci----
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci*process_event*, if defined, is called for any non-tracepoint event
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci----
55662306a36Sopenharmony_cidef process_event(param_dict):
55762306a36Sopenharmony_ci    pass
55862306a36Sopenharmony_ci----
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci*context_switch*, if defined, is called for any context switch
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci----
56362306a36Sopenharmony_cidef context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x):
56462306a36Sopenharmony_ci    pass
56562306a36Sopenharmony_ci----
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci*auxtrace_error*, if defined, is called for any AUX area tracing error
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci----
57062306a36Sopenharmony_cidef auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x):
57162306a36Sopenharmony_ci    pass
57262306a36Sopenharmony_ci----
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ciThe remaining sections provide descriptions of each of the available
57562306a36Sopenharmony_cibuilt-in perf script Python modules and their associated functions.
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ciAVAILABLE MODULES AND FUNCTIONS
57862306a36Sopenharmony_ci-------------------------------
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_ciThe following sections describe the functions and variables available
58162306a36Sopenharmony_civia the various perf script Python modules.  To use the functions and
58262306a36Sopenharmony_civariables from the given module, add the corresponding 'from XXXX
58362306a36Sopenharmony_ciimport' line to your perf script script.
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ciCore.py Module
58662306a36Sopenharmony_ci~~~~~~~~~~~~~~
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ciThese functions provide some essential functions to user scripts.
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ciThe *flag_str* and *symbol_str* functions provide human-readable
59162306a36Sopenharmony_cistrings for flag and symbolic fields.  These correspond to the strings
59262306a36Sopenharmony_ciand values parsed from the 'print fmt' fields of the event format
59362306a36Sopenharmony_cifiles:
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci  flag_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the flag field field_name of event event_name
59662306a36Sopenharmony_ci  symbol_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the symbolic field field_name of event event_name
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ciThe *autodict* function returns a special kind of Python
59962306a36Sopenharmony_cidictionary that implements Perl's 'autovivifying' hashes in Python
60062306a36Sopenharmony_cii.e. with autovivifying hashes, you can assign nested hash values
60162306a36Sopenharmony_ciwithout having to go to the trouble of creating intermediate levels if
60262306a36Sopenharmony_cithey don't exist.
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci  autodict() - returns an autovivifying dictionary instance
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ciperf_trace_context Module
60862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ciSome of the 'common' fields in the event format file aren't all that
61162306a36Sopenharmony_cicommon, but need to be made accessible to user scripts nonetheless.
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ciperf_trace_context defines a set of functions that can be used to
61462306a36Sopenharmony_ciaccess this data in the context of the current event.  Each of these
61562306a36Sopenharmony_cifunctions expects a context variable, which is the same as the
61662306a36Sopenharmony_cicontext variable passed into every tracepoint event handler as the second
61762306a36Sopenharmony_ciargument. For non-tracepoint events, the context variable is also present
61862306a36Sopenharmony_cias perf_trace_context.perf_script_context .
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci common_pc(context) - returns common_preempt count for the current event
62162306a36Sopenharmony_ci common_flags(context) - returns common_flags for the current event
62262306a36Sopenharmony_ci common_lock_depth(context) - returns common_lock_depth for the current event
62362306a36Sopenharmony_ci perf_sample_insn(context) - returns the machine code instruction
62462306a36Sopenharmony_ci perf_set_itrace_options(context, itrace_options) - set --itrace options if they have not been set already
62562306a36Sopenharmony_ci perf_sample_srcline(context) - returns source_file_name, line_number
62662306a36Sopenharmony_ci perf_sample_srccode(context) - returns source_file_name, line_number, source_line
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ciUtil.py Module
63062306a36Sopenharmony_ci~~~~~~~~~~~~~~
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ciVarious utility functions for use with perf script:
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci  nsecs(secs, nsecs) - returns total nsecs given secs/nsecs pair
63562306a36Sopenharmony_ci  nsecs_secs(nsecs) - returns whole secs portion given nsecs
63662306a36Sopenharmony_ci  nsecs_nsecs(nsecs) - returns nsecs remainder given nsecs
63762306a36Sopenharmony_ci  nsecs_str(nsecs) - returns printable string in the form secs.nsecs
63862306a36Sopenharmony_ci  avg(total, n) - returns average given a sum and a total number of values
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ciSUPPORTED FIELDS
64162306a36Sopenharmony_ci----------------
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ciCurrently supported fields:
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ciev_name, comm, pid, tid, cpu, ip, time, period, phys_addr, addr,
64662306a36Sopenharmony_cisymbol, symoff, dso, time_enabled, time_running, values, callchain,
64762306a36Sopenharmony_cibrstack, brstacksym, datasrc, datasrc_decode, iregs, uregs,
64862306a36Sopenharmony_ciweight, transaction, raw_buf, attr, cpumode.
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ciFields that may also be present:
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci flags - sample flags
65362306a36Sopenharmony_ci flags_disp - sample flags display
65462306a36Sopenharmony_ci insn_cnt - instruction count for determining instructions-per-cycle (IPC)
65562306a36Sopenharmony_ci cyc_cnt - cycle count for determining IPC
65662306a36Sopenharmony_ci addr_correlates_sym - addr can correlate to a symbol
65762306a36Sopenharmony_ci addr_dso - addr dso
65862306a36Sopenharmony_ci addr_symbol - addr symbol
65962306a36Sopenharmony_ci addr_symoff - addr symbol offset
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ciSome fields have sub items:
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_cibrstack:
66462306a36Sopenharmony_ci    from, to, from_dsoname, to_dsoname, mispred,
66562306a36Sopenharmony_ci    predicted, in_tx, abort, cycles.
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_cibrstacksym:
66862306a36Sopenharmony_ci    items: from, to, pred, in_tx, abort (converted string)
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ciFor example,
67162306a36Sopenharmony_ciWe can use this code to print brstack "from", "to", "cycles".
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ciif 'brstack' in dict:
67462306a36Sopenharmony_ci	for entry in dict['brstack']:
67562306a36Sopenharmony_ci		print "from %s, to %s, cycles %s" % (entry["from"], entry["to"], entry["cycles"])
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ciSEE ALSO
67862306a36Sopenharmony_ci--------
67962306a36Sopenharmony_cilinkperf:perf-script[1]
680