diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2021-05-25 11:51:12 +0200 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2021-05-25 15:07:17 +0200 |
commit | a92bf335fd82eeee0e95705bfd25014ee0c8262e (patch) | |
tree | 6c2e7f6937bd83f511ac7a9a9d7e676340616e3c /tools/perf/scripts | |
parent | perf scripting python: Add auxtrace error (diff) | |
download | linux-a92bf335fd82eeee0e95705bfd25014ee0c8262e.tar.xz linux-a92bf335fd82eeee0e95705bfd25014ee0c8262e.zip |
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>
Diffstat (limited to 'tools/perf/scripts')
-rw-r--r-- | tools/perf/scripts/python/bin/intel-pt-events-record | 4 | ||||
-rw-r--r-- | tools/perf/scripts/python/bin/intel-pt-events-report | 4 | ||||
-rw-r--r-- | tools/perf/scripts/python/intel-pt-events.py | 143 |
3 files changed, 116 insertions, 35 deletions
diff --git a/tools/perf/scripts/python/bin/intel-pt-events-record b/tools/perf/scripts/python/bin/intel-pt-events-record index 10fe2b6977d4..6b9877cfe23e 100644 --- a/tools/perf/scripts/python/bin/intel-pt-events-record +++ b/tools/perf/scripts/python/bin/intel-pt-events-record @@ -1,8 +1,8 @@ #!/bin/bash # -# print Intel PT Power Events and PTWRITE. The intel_pt PMU event needs -# to be specified with appropriate config terms. +# print Intel PT Events including Power Events and PTWRITE. The intel_pt PMU +# event needs to be specified with appropriate config terms. # if ! echo "$@" | grep -q intel_pt ; then echo "Options must include the Intel PT event e.g. -e intel_pt/pwr_evt,ptw/" diff --git a/tools/perf/scripts/python/bin/intel-pt-events-report b/tools/perf/scripts/python/bin/intel-pt-events-report index 9a9c92fcd026..beeac3fde9db 100644 --- a/tools/perf/scripts/python/bin/intel-pt-events-report +++ b/tools/perf/scripts/python/bin/intel-pt-events-report @@ -1,3 +1,3 @@ #!/bin/bash -# description: print Intel PT Power Events and PTWRITE -perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py
\ No newline at end of file +# description: print Intel PT Events including Power Events and PTWRITE +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/intel-pt-events.py diff --git a/tools/perf/scripts/python/intel-pt-events.py b/tools/perf/scripts/python/intel-pt-events.py index a73847c8f548..fcfae1de731b 100644 --- a/tools/perf/scripts/python/intel-pt-events.py +++ b/tools/perf/scripts/python/intel-pt-events.py @@ -1,5 +1,6 @@ -# intel-pt-events.py: Print Intel PT Power Events and PTWRITE -# Copyright (c) 2017, Intel Corporation. +# SPDX-License-Identifier: GPL-2.0 +# intel-pt-events.py: Print Intel PT Events including Power Events and PTWRITE +# Copyright (c) 2017-2021, Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, @@ -23,8 +24,36 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ #from perf_trace_context import * #from Core import * +try: + broken_pipe_exception = BrokenPipeError +except: + broken_pipe_exception = IOError + +glb_switch_str = None +glb_switch_printed = True + +def get_optional_null(perf_dict, field): + if field in perf_dict: + return perf_dict[field] + return "" + +def get_optional_zero(perf_dict, field): + if field in perf_dict: + return perf_dict[field] + return 0 + +def get_optional(perf_dict, field): + if field in perf_dict: + return perf_dict[field] + return "[unknown]" + +def get_offset(perf_dict, field): + if field in perf_dict: + return "+%#x" % perf_dict[field] + return "" + def trace_begin(): - print("Intel PT Power Events and PTWRITE") + print("Intel PT Branch Trace, Power Events and PTWRITE") def trace_end(): print("End") @@ -77,58 +106,110 @@ def print_pwrx(raw_buf): print("deepest cstate: %u last cstate: %u wake reason: %#x" % (deepest_cstate, last_cstate, wake_reason), end=' ') +def print_psb(raw_buf): + data = struct.unpack_from("<IQ", raw_buf) + offset = data[1] + print("offset: %#x" % (offset), end=' ') + def print_common_start(comm, sample, name): ts = sample["time"] cpu = sample["cpu"] pid = sample["pid"] tid = sample["tid"] - print("%16s %5u/%-5u [%03u] %9u.%09u %7s:" % - (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name), + flags_disp = get_optional_null(sample, "flags_disp") + # Unused fields: + # period = sample["period"] + # phys_addr = sample["phys_addr"] + # weight = sample["weight"] + # transaction = sample["transaction"] + # cpumode = get_optional_zero(sample, "cpumode") + print("%16s %5u/%-5u [%03u] %9u.%09u %7s %19s" % + (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name, flags_disp), end=' ') -def print_common_ip(sample, symbol, dso): - ip = sample["ip"] - print("%16x %s (%s)" % (ip, symbol, dso)) +def print_common_ip(param_dict, sample, symbol, dso): + ip = sample["ip"] + offs = get_offset(param_dict, "symoff") + print("%16x %s%s (%s)" % (ip, symbol, offs, dso), end=' ') + if "addr_correlates_sym" in sample: + addr = sample["addr"] + dso = get_optional(sample, "addr_dso") + symbol = get_optional(sample, "addr_symbol") + offs = get_offset(sample, "addr_symoff") + print("=> %x %s%s (%s)" % (addr, symbol, offs, dso)) + else: + print() -def process_event(param_dict): +def do_process_event(param_dict): + global glb_switch_printed + if not glb_switch_printed: + print(glb_switch_str) + glb_switch_printed = True event_attr = param_dict["attr"] - sample = param_dict["sample"] - raw_buf = param_dict["raw_buf"] + sample = param_dict["sample"] + raw_buf = param_dict["raw_buf"] comm = param_dict["comm"] name = param_dict["ev_name"] + # Unused fields: + # callchain = param_dict["callchain"] + # brstack = param_dict["brstack"] + # brstacksym = param_dict["brstacksym"] # Symbol and dso info are not always resolved - if "dso" in param_dict: - dso = param_dict["dso"] - else: - dso = "[unknown]" + dso = get_optional(param_dict, "dso") + symbol = get_optional(param_dict, "symbol") - if "symbol" in param_dict: - symbol = param_dict["symbol"] - else: - symbol = "[unknown]" + print_common_start(comm, sample, name) if name == "ptwrite": - print_common_start(comm, sample, name) print_ptwrite(raw_buf) - print_common_ip(sample, symbol, dso) elif name == "cbr": - print_common_start(comm, sample, name) print_cbr(raw_buf) - print_common_ip(sample, symbol, dso) elif name == "mwait": - print_common_start(comm, sample, name) print_mwait(raw_buf) - print_common_ip(sample, symbol, dso) elif name == "pwre": - print_common_start(comm, sample, name) print_pwre(raw_buf) - print_common_ip(sample, symbol, dso) elif name == "exstop": - print_common_start(comm, sample, name) print_exstop(raw_buf) - print_common_ip(sample, symbol, dso) elif name == "pwrx": - print_common_start(comm, sample, name) print_pwrx(raw_buf) - print_common_ip(sample, symbol, dso) + elif name == "psb": + print_psb(raw_buf) + + print_common_ip(param_dict, sample, symbol, dso) + +def process_event(param_dict): + try: + do_process_event(param_dict) + except broken_pipe_exception: + # Stop python printing broken pipe errors and traceback + sys.stdout = open(os.devnull, 'w') + sys.exit(1) + +def auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x): + try: + print("%16s %5u/%-5u [%03u] %9u.%09u error type %u code %u: %s ip 0x%16x" % + ("Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip)) + except broken_pipe_exception: + # Stop python printing broken pipe errors and traceback + sys.stdout = open(os.devnull, 'w') + sys.exit(1) + +def context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x): + global glb_switch_printed + global glb_switch_str + if out: + out_str = "Switch out " + else: + out_str = "Switch In " + if out_preempt: + preempt_str = "preempt" + else: + preempt_str = "" + if machine_pid == -1: + machine_str = "" + else: + machine_str = "machine PID %d" % machine_pid + glb_switch_str = "%16s %5d/%-5d [%03u] %9u.%09u %5d/%-5d %s %s" % \ + (out_str, pid, tid, cpu, ts / 1000000000, ts %1000000000, np_pid, np_tid, machine_str, preempt_str) + glb_switch_printed = False |