diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 4f34379ebd775d1a0a53f2c52ad152c12222a628..a46030d8962d2ba73a80b58fa9ac4dc72987786a 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -170,7 +170,12 @@ OPTIONS 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. + respectively. Known combinations of flags are printed more nicely e.g. + "call" for "bc", "return" for "br", "jcc" for "bo", "jmp" for "b", + "int" for "bci", "iret" for "bri", "syscall" for "bcs", "sysret" for "brs", + "async" for "by", "hw int" for "bcyi", "tx abrt" for "bA", "tr strt" for "bB", + "tr end" for "bE". However the "x" flag will be display separately in those + cases e.g. "jcc (x)" for a condition branch within a transaction. 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 0e18e06e7fd58098eba6caa84f8d80aaa9d72cb6..56b2fb8135ce5add5a06f03ce4b4b306a677c5fc 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -606,13 +606,42 @@ static void print_sample_bts(struct perf_sample *sample, printf("\n"); } +static struct { + u32 flags; + const char *name; +} sample_flags[] = { + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, + {PERF_IP_FLAG_BRANCH, "jmp"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, + {0, NULL} +}; + static void print_sample_flags(u32 flags) { const char *chars = PERF_IP_FLAG_CHARS; const int n = strlen(PERF_IP_FLAG_CHARS); + bool in_tx = flags & PERF_IP_FLAG_IN_TX; + const char *name = NULL; char str[33]; int i, pos = 0; + for (i = 0; sample_flags[i].name ; i++) { + if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) { + name = sample_flags[i].name; + break; + } + } + for (i = 0; i < n; i++, flags >>= 1) { if (flags & 1) str[pos++] = chars[i]; @@ -622,7 +651,11 @@ static void print_sample_flags(u32 flags) str[pos++] = '?'; } str[pos] = 0; - printf(" %-4s ", str); + + if (name) + printf(" %-7s%4s ", name, in_tx ? "(x)" : ""); + else + printf(" %-11s ", str); } struct printer_data {