History

perf scripts python: intel-pt-events.py: Add branches to script

As an example, add branch information to intel-pt-events.py script. This shows how a simple python script can be used to customize perf script output for Intel PT branch traces or power event traces.

Adrian Hunter committed 5 years ago

Commit a92bf331 parent 2ede9213 files · +116 −35Browse files

Showing the changes to tools/perf/scripts/python (3 of 3 files). Show all

Unified · Split

3 files
  1. tools/perf/scripts/python/bin/intel-pt-events-record +2 −2
  2. tools/perf/scripts/python/bin/intel-pt-events-report +2 −2
  3. tools/perf/scripts/python/intel-pt-events.py +112 −31
tools/perf/scripts/python/bin/intel-pt-events-record+2−2
@@ -1,8 +1,8 @@
11 #!/bin/bash
22
33 #
4−# print Intel PT Power Events and PTWRITE. The intel_pt PMU event needs
5−# to be specified with appropriate config terms.
4+# print Intel PT Events including Power Events and PTWRITE. The intel_pt PMU
5+# event needs to be specified with appropriate config terms.
66 #
77 if ! echo "$@" | grep -q intel_pt ; then
88 echo "Options must include the Intel PT event e.g. -e intel_pt/pwr_evt,ptw/"
tools/perf/scripts/python/bin/intel-pt-events-report+2−2
@@ -1,3 +1,3 @@
11 #!/bin/bash
2−# description: print Intel PT Power Events and PTWRITE
3−perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py
2+# description: print Intel PT Events including Power Events and PTWRITE
3+perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py
tools/perf/scripts/python/intel-pt-events.py+112−31
@@ -1,5 +1,6 @@
1−# intel-pt-events.py: Print Intel PT Power Events and PTWRITE
2−# Copyright (c) 2017, Intel Corporation.
1+# SPDX-License-Identifier: GPL-2.0
2+# intel-pt-events.py: Print Intel PT Events including Power Events and PTWRITE
3+# Copyright (c) 2017-2021, Intel Corporation.
34 #
45 # This program is free software; you can redistribute it and/or modify it
56 # under the terms and conditions of the GNU General Public License,
@@ -23,8 +24,36 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ · 17 unmodified lines
2324 #from perf_trace_context import *
2425 #from Core import *
2526
27+try:
28+ broken_pipe_exception = BrokenPipeError
29+except:
30+ broken_pipe_exception = IOError
31+
32+glb_switch_str = None
33+glb_switch_printed = True
34+
35+def get_optional_null(perf_dict, field):
36+ if field in perf_dict:
37+ return perf_dict[field]
38+ return ""
39+
40+def get_optional_zero(perf_dict, field):
41+ if field in perf_dict:
42+ return perf_dict[field]
43+ return 0
44+
45+def get_optional(perf_dict, field):
46+ if field in perf_dict:
47+ return perf_dict[field]
48+ return "[unknown]"
49+
50+def get_offset(perf_dict, field):
51+ if field in perf_dict:
52+ return "+%#x" % perf_dict[field]
53+ return ""
54+
2655 def trace_begin():
27− print("Intel PT Power Events and PTWRITE")
56+ print("Intel PT Branch Trace, Power Events and PTWRITE")
2857
2958 def trace_end():
3059 print("End")
@@ -77,58 +106,110 @@ def print_pwrx(raw_buf): · 46 unmodified lines
77106 print("deepest cstate: %u last cstate: %u wake reason: %#x" %
78107 (deepest_cstate, last_cstate, wake_reason), end=' ')
79108
109+def print_psb(raw_buf):
110+ data = struct.unpack_from("<IQ", raw_buf)
111+ offset = data[1]
112+ print("offset: %#x" % (offset), end=' ')
113+
80114 def print_common_start(comm, sample, name):
81115 ts = sample["time"]
82116 cpu = sample["cpu"]
83117 pid = sample["pid"]
84118 tid = sample["tid"]
85− print("%16s %5u/%-5u [%03u] %9u.%09u %7s:" %
86− (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name),
119+ flags_disp = get_optional_null(sample, "flags_disp")
120+ # Unused fields:
121+ # period = sample["period"]
122+ # phys_addr = sample["phys_addr"]
123+ # weight = sample["weight"]
124+ # transaction = sample["transaction"]
125+ # cpumode = get_optional_zero(sample, "cpumode")
126+ print("%16s %5u/%-5u [%03u] %9u.%09u %7s %19s" %
127+ (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name, flags_disp),
87128 end=' ')
88129
89−def print_common_ip(sample, symbol, dso):
90− ip = sample["ip"]
91− print("%16x %s (%s)" % (ip, symbol, dso))
130+def print_common_ip(param_dict, sample, symbol, dso):
131+ ip = sample["ip"]
132+ offs = get_offset(param_dict, "symoff")
133+ print("%16x %s%s (%s)" % (ip, symbol, offs, dso), end=' ')
134+ if "addr_correlates_sym" in sample:
135+ addr = sample["addr"]
136+ dso = get_optional(sample, "addr_dso")
137+ symbol = get_optional(sample, "addr_symbol")
138+ offs = get_offset(sample, "addr_symoff")
139+ print("=> %x %s%s (%s)" % (addr, symbol, offs, dso))
140+ else:
141+ print()
92142
93−def process_event(param_dict):
143+def do_process_event(param_dict):
144+ global glb_switch_printed
145+ if not glb_switch_printed:
146+ print(glb_switch_str)
147+ glb_switch_printed = True
94148 event_attr = param_dict["attr"]
95− sample = param_dict["sample"]
96− raw_buf = param_dict["raw_buf"]
149+ sample = param_dict["sample"]
150+ raw_buf = param_dict["raw_buf"]
97151 comm = param_dict["comm"]
98152 name = param_dict["ev_name"]
153+ # Unused fields:
154+ # callchain = param_dict["callchain"]
155+ # brstack = param_dict["brstack"]
156+ # brstacksym = param_dict["brstacksym"]
99157
100158 # Symbol and dso info are not always resolved
101− if "dso" in param_dict:
102− dso = param_dict["dso"]
103− else:
104− dso = "[unknown]"
159+ dso = get_optional(param_dict, "dso")
160+ symbol = get_optional(param_dict, "symbol")
105161
106− if "symbol" in param_dict:
107− symbol = param_dict["symbol"]
108− else:
109− symbol = "[unknown]"
162+ print_common_start(comm, sample, name)
110163
111164 if name == "ptwrite":
112− print_common_start(comm, sample, name)
113165 print_ptwrite(raw_buf)
114− print_common_ip(sample, symbol, dso)
115166 elif name == "cbr":
116− print_common_start(comm, sample, name)
117167 print_cbr(raw_buf)
118− print_common_ip(sample, symbol, dso)
119168 elif name == "mwait":
120− print_common_start(comm, sample, name)
121169 print_mwait(raw_buf)
122− print_common_ip(sample, symbol, dso)
123170 elif name == "pwre":
124− print_common_start(comm, sample, name)
125171 print_pwre(raw_buf)
126− print_common_ip(sample, symbol, dso)
127172 elif name == "exstop":
128− print_common_start(comm, sample, name)
129173 print_exstop(raw_buf)
130− print_common_ip(sample, symbol, dso)
131174 elif name == "pwrx":
132− print_common_start(comm, sample, name)
133175 print_pwrx(raw_buf)
134− print_common_ip(sample, symbol, dso)
176+ elif name == "psb":
177+ print_psb(raw_buf)
178+
179+ print_common_ip(param_dict, sample, symbol, dso)
180+
181+def process_event(param_dict):
182+ try:
183+ do_process_event(param_dict)
184+ except broken_pipe_exception:
185+ # Stop python printing broken pipe errors and traceback
186+ sys.stdout = open(os.devnull, 'w')
187+ sys.exit(1)
188+
189+def auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x):
190+ try:
191+ print("%16s %5u/%-5u [%03u] %9u.%09u error type %u code %u: %s ip 0x%16x" %
192+ ("Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip))
193+ except broken_pipe_exception:
194+ # Stop python printing broken pipe errors and traceback
195+ sys.stdout = open(os.devnull, 'w')
196+ sys.exit(1)
197+
198+def context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x):
199+ global glb_switch_printed
200+ global glb_switch_str
201+ if out:
202+ out_str = "Switch out "
203+ else:
204+ out_str = "Switch In "
205+ if out_preempt:
206+ preempt_str = "preempt"
207+ else:
208+ preempt_str = ""
209+ if machine_pid == -1:
210+ machine_str = ""
211+ else:
212+ machine_str = "machine PID %d" % machine_pid
213+ glb_switch_str = "%16s %5d/%-5d [%03u] %9u.%09u %5d/%-5d %s %s" % \
214+ (out_str, pid, tid, cpu, ts / 1000000000, ts %1000000000, np_pid, np_tid, machine_str, preempt_str)
215+ glb_switch_printed = False