Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: https://lore.kernel.org/r/20210525095112.1399-11-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
a92bf335 2ede9217

+115 -34
+2 -2
tools/perf/scripts/python/bin/intel-pt-events-record
··· 1 1 #!/bin/bash 2 2 3 3 # 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. 6 6 # 7 7 if ! echo "$@" | grep -q intel_pt ; then 8 8 echo "Options must include the Intel PT event e.g. -e intel_pt/pwr_evt,ptw/"
+1 -1
tools/perf/scripts/python/bin/intel-pt-events-report
··· 1 1 #!/bin/bash 2 - # description: print Intel PT Power Events and PTWRITE 2 + # description: print Intel PT Events including Power Events and PTWRITE 3 3 perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py
+112 -31
tools/perf/scripts/python/intel-pt-events.py
··· 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. 3 4 # 4 5 # This program is free software; you can redistribute it and/or modify it 5 6 # under the terms and conditions of the GNU General Public License, ··· 24 23 #from perf_trace_context import * 25 24 #from Core import * 26 25 26 + try: 27 + broken_pipe_exception = BrokenPipeError 28 + except: 29 + broken_pipe_exception = IOError 30 + 31 + glb_switch_str = None 32 + glb_switch_printed = True 33 + 34 + def get_optional_null(perf_dict, field): 35 + if field in perf_dict: 36 + return perf_dict[field] 37 + return "" 38 + 39 + def get_optional_zero(perf_dict, field): 40 + if field in perf_dict: 41 + return perf_dict[field] 42 + return 0 43 + 44 + def get_optional(perf_dict, field): 45 + if field in perf_dict: 46 + return perf_dict[field] 47 + return "[unknown]" 48 + 49 + def get_offset(perf_dict, field): 50 + if field in perf_dict: 51 + return "+%#x" % perf_dict[field] 52 + return "" 53 + 27 54 def trace_begin(): 28 - print("Intel PT Power Events and PTWRITE") 55 + print("Intel PT Branch Trace, Power Events and PTWRITE") 29 56 30 57 def trace_end(): 31 58 print("End") ··· 106 77 print("deepest cstate: %u last cstate: %u wake reason: %#x" % 107 78 (deepest_cstate, last_cstate, wake_reason), end=' ') 108 79 80 + def print_psb(raw_buf): 81 + data = struct.unpack_from("<IQ", raw_buf) 82 + offset = data[1] 83 + print("offset: %#x" % (offset), end=' ') 84 + 109 85 def print_common_start(comm, sample, name): 110 86 ts = sample["time"] 111 87 cpu = sample["cpu"] 112 88 pid = sample["pid"] 113 89 tid = sample["tid"] 114 - print("%16s %5u/%-5u [%03u] %9u.%09u %7s:" % 115 - (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name), 90 + flags_disp = get_optional_null(sample, "flags_disp") 91 + # Unused fields: 92 + # period = sample["period"] 93 + # phys_addr = sample["phys_addr"] 94 + # weight = sample["weight"] 95 + # transaction = sample["transaction"] 96 + # cpumode = get_optional_zero(sample, "cpumode") 97 + print("%16s %5u/%-5u [%03u] %9u.%09u %7s %19s" % 98 + (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name, flags_disp), 116 99 end=' ') 117 100 118 - def print_common_ip(sample, symbol, dso): 119 - ip = sample["ip"] 120 - print("%16x %s (%s)" % (ip, symbol, dso)) 101 + def print_common_ip(param_dict, sample, symbol, dso): 102 + ip = sample["ip"] 103 + offs = get_offset(param_dict, "symoff") 104 + print("%16x %s%s (%s)" % (ip, symbol, offs, dso), end=' ') 105 + if "addr_correlates_sym" in sample: 106 + addr = sample["addr"] 107 + dso = get_optional(sample, "addr_dso") 108 + symbol = get_optional(sample, "addr_symbol") 109 + offs = get_offset(sample, "addr_symoff") 110 + print("=> %x %s%s (%s)" % (addr, symbol, offs, dso)) 111 + else: 112 + print() 121 113 122 - def process_event(param_dict): 114 + def do_process_event(param_dict): 115 + global glb_switch_printed 116 + if not glb_switch_printed: 117 + print(glb_switch_str) 118 + glb_switch_printed = True 123 119 event_attr = param_dict["attr"] 124 - sample = param_dict["sample"] 125 - raw_buf = param_dict["raw_buf"] 120 + sample = param_dict["sample"] 121 + raw_buf = param_dict["raw_buf"] 126 122 comm = param_dict["comm"] 127 123 name = param_dict["ev_name"] 124 + # Unused fields: 125 + # callchain = param_dict["callchain"] 126 + # brstack = param_dict["brstack"] 127 + # brstacksym = param_dict["brstacksym"] 128 128 129 129 # Symbol and dso info are not always resolved 130 - if "dso" in param_dict: 131 - dso = param_dict["dso"] 132 - else: 133 - dso = "[unknown]" 130 + dso = get_optional(param_dict, "dso") 131 + symbol = get_optional(param_dict, "symbol") 134 132 135 - if "symbol" in param_dict: 136 - symbol = param_dict["symbol"] 137 - else: 138 - symbol = "[unknown]" 133 + print_common_start(comm, sample, name) 139 134 140 135 if name == "ptwrite": 141 - print_common_start(comm, sample, name) 142 136 print_ptwrite(raw_buf) 143 - print_common_ip(sample, symbol, dso) 144 137 elif name == "cbr": 145 - print_common_start(comm, sample, name) 146 138 print_cbr(raw_buf) 147 - print_common_ip(sample, symbol, dso) 148 139 elif name == "mwait": 149 - print_common_start(comm, sample, name) 150 140 print_mwait(raw_buf) 151 - print_common_ip(sample, symbol, dso) 152 141 elif name == "pwre": 153 - print_common_start(comm, sample, name) 154 142 print_pwre(raw_buf) 155 - print_common_ip(sample, symbol, dso) 156 143 elif name == "exstop": 157 - print_common_start(comm, sample, name) 158 144 print_exstop(raw_buf) 159 - print_common_ip(sample, symbol, dso) 160 145 elif name == "pwrx": 161 - print_common_start(comm, sample, name) 162 146 print_pwrx(raw_buf) 163 - print_common_ip(sample, symbol, dso) 147 + elif name == "psb": 148 + print_psb(raw_buf) 149 + 150 + print_common_ip(param_dict, sample, symbol, dso) 151 + 152 + def process_event(param_dict): 153 + try: 154 + do_process_event(param_dict) 155 + except broken_pipe_exception: 156 + # Stop python printing broken pipe errors and traceback 157 + sys.stdout = open(os.devnull, 'w') 158 + sys.exit(1) 159 + 160 + def auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x): 161 + try: 162 + print("%16s %5u/%-5u [%03u] %9u.%09u error type %u code %u: %s ip 0x%16x" % 163 + ("Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip)) 164 + except broken_pipe_exception: 165 + # Stop python printing broken pipe errors and traceback 166 + sys.stdout = open(os.devnull, 'w') 167 + sys.exit(1) 168 + 169 + def context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x): 170 + global glb_switch_printed 171 + global glb_switch_str 172 + if out: 173 + out_str = "Switch out " 174 + else: 175 + out_str = "Switch In " 176 + if out_preempt: 177 + preempt_str = "preempt" 178 + else: 179 + preempt_str = "" 180 + if machine_pid == -1: 181 + machine_str = "" 182 + else: 183 + machine_str = "machine PID %d" % machine_pid 184 + glb_switch_str = "%16s %5d/%-5d [%03u] %9u.%09u %5d/%-5d %s %s" % \ 185 + (out_str, pid, tid, cpu, ts / 1000000000, ts %1000000000, np_pid, np_tid, machine_str, preempt_str) 186 + glb_switch_printed = False