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