diff options
-rw-r--r-- | tools/perf/Documentation/perf-script.txt | 9 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 34 | ||||
-rw-r--r-- | tools/perf/util/event.h | 2 |
3 files changed, 39 insertions, 6 deletions
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 05df64804def..b29cd2f17d13 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -115,7 +115,8 @@ OPTIONS -f:: --fields:: Comma separated list of fields to print. Options are: - comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period. + comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, + srcline, period, flags. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace @@ -165,6 +166,12 @@ OPTIONS At this point usage is displayed, and perf-script exits. + The flags field is synthesized and may have a value when Instruction + Trace decoding. The flags are "bcrosyiABEx" which stand for branch, + call, return, conditional, system, asynchronous, interrupt, + transaction abort, trace begin, trace end, and in transaction, + respectively. + Finally, a user may not set fields to none for all event types. i.e., -f "" is not allowed. diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7682665456fe..cd2f38bf7573 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -27,6 +27,7 @@ static u64 nr_unordered; static bool no_callchain; static bool latency_format; static bool system_wide; +static bool print_flags; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); @@ -446,6 +447,25 @@ static void print_sample_bts(union perf_event *event, printf("\n"); } +static void print_sample_flags(u32 flags) +{ + const char *chars = PERF_IP_FLAG_CHARS; + const int n = strlen(PERF_IP_FLAG_CHARS); + char str[33]; + int i, pos = 0; + + for (i = 0; i < n; i++, flags >>= 1) { + if (flags & 1) + str[pos++] = chars[i]; + } + for (; i < 32; i++, flags >>= 1) { + if (flags & 1) + str[pos++] = '?'; + } + str[pos] = 0; + printf(" %-4s ", str); +} + static void process_event(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al) { @@ -465,6 +485,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf("%s: ", evname ? evname : "[unknown]"); } + if (print_flags) + print_sample_flags(sample->flags); + if (is_bts_event(attr)) { print_sample_bts(event, sample, evsel, thread, al); return; @@ -1000,12 +1023,15 @@ static int parse_output_fields(const struct option *opt __maybe_unused, } } - tok = strtok(tok, ","); - while (tok) { + for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) { for (i = 0; i < imax; ++i) { if (strcmp(tok, all_output_options[i].str) == 0) break; } + if (i == imax && strcmp(tok, "flags") == 0) { + print_flags = true; + continue; + } if (i == imax) { fprintf(stderr, "Invalid field requested.\n"); rc = -EINVAL; @@ -1033,8 +1059,6 @@ static int parse_output_fields(const struct option *opt __maybe_unused, } output[type].fields |= all_output_options[i].field; } - - tok = strtok(NULL, ","); } if (type >= 0) { @@ -1555,7 +1579,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) "comma separated output fields prepend with 'type:'. " "Valid types: hw,sw,trace,raw. " "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," - "addr,symoff,period", parse_output_fields), + "addr,symoff,period,flags", parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 8ef37251a7a9..80e9f5969a39 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -157,6 +157,8 @@ enum { PERF_IP_FLAG_IN_TX = 1ULL << 10, }; +#define PERF_IP_FLAG_CHARS "bcrosyiABEx" + #define PERF_BRANCH_MASK (\ PERF_IP_FLAG_BRANCH |\ PERF_IP_FLAG_CALL |\ |