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

perf script: Print sample flags more nicely

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.

Change the display so that 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 displayed separately in those cases e.g.
"jcc (x)" for a condition branch within a transaction.

Example:

perf record -e intel_pt//u ls
perf script --ns -F comm,cpu,pid,tid,time,ip,addr,sym,dso,symoff,flags
...
ls 3689/3689 [001] 2062.020965237: jcc 7f06a958847a _dl_sysdep_start+0xfa (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a9588450 _dl_sysdep_start+0xd0 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020965237: jmp 7f06a9588461 _dl_sysdep_start+0xe1 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a95885a0 _dl_sysdep_start+0x220 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020965237: jmp 7f06a95885a4 _dl_sysdep_start+0x224 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a9588470 _dl_sysdep_start+0xf0 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020965904: call 7f06a95884c3 _dl_sysdep_start+0x143 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a9589140 brk+0x0 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020965904: syscall 7f06a958914a brk+0xa (/lib/x86_64-linux-gnu/ld-2.19.so) => 0 [unknown] ([unknown])
ls 3689/3689 [001] 2062.020966237: tr strt 0 [unknown] ([unknown]) => 7f06a958914c brk+0xc (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020966237: return 7f06a9589165 brk+0x25 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a95884c8 _dl_sysdep_start+0x148 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020966237: jcc 7f06a95884d7 _dl_sysdep_start+0x157 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a95885f0 _dl_sysdep_start+0x270 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020966237: call 7f06a95885f0 _dl_sysdep_start+0x270 (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a958ac50 strlen+0x0 (/lib/x86_64-linux-gnu/ld-2.19.so)
ls 3689/3689 [001] 2062.020966237: jcc 7f06a958ac6e strlen+0x1e (/lib/x86_64-linux-gnu/ld-2.19.so) => 7f06a958ac60 strlen+0x10 (/lib/x86_64-linux-gnu/ld-2.19.so)
...

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1466689258-28493-2-git-send-email-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
055cd33d 10daf4d0

+40 -2
+6 -1
tools/perf/Documentation/perf-script.txt
··· 170 170 Trace decoding. The flags are "bcrosyiABEx" which stand for branch, 171 171 call, return, conditional, system, asynchronous, interrupt, 172 172 transaction abort, trace begin, trace end, and in transaction, 173 - respectively. 173 + respectively. Known combinations of flags are printed more nicely e.g. 174 + "call" for "bc", "return" for "br", "jcc" for "bo", "jmp" for "b", 175 + "int" for "bci", "iret" for "bri", "syscall" for "bcs", "sysret" for "brs", 176 + "async" for "by", "hw int" for "bcyi", "tx abrt" for "bA", "tr strt" for "bB", 177 + "tr end" for "bE". However the "x" flag will be display separately in those 178 + cases e.g. "jcc (x)" for a condition branch within a transaction. 174 179 175 180 Finally, a user may not set fields to none for all event types. 176 181 i.e., -F "" is not allowed.
+34 -1
tools/perf/builtin-script.c
··· 606 606 printf("\n"); 607 607 } 608 608 609 + static struct { 610 + u32 flags; 611 + const char *name; 612 + } sample_flags[] = { 613 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, 614 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, 615 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, 616 + {PERF_IP_FLAG_BRANCH, "jmp"}, 617 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, 618 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, 619 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, 620 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, 621 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, 622 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"}, 623 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, 624 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, 625 + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, 626 + {0, NULL} 627 + }; 628 + 609 629 static void print_sample_flags(u32 flags) 610 630 { 611 631 const char *chars = PERF_IP_FLAG_CHARS; 612 632 const int n = strlen(PERF_IP_FLAG_CHARS); 633 + bool in_tx = flags & PERF_IP_FLAG_IN_TX; 634 + const char *name = NULL; 613 635 char str[33]; 614 636 int i, pos = 0; 637 + 638 + for (i = 0; sample_flags[i].name ; i++) { 639 + if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) { 640 + name = sample_flags[i].name; 641 + break; 642 + } 643 + } 615 644 616 645 for (i = 0; i < n; i++, flags >>= 1) { 617 646 if (flags & 1) ··· 651 622 str[pos++] = '?'; 652 623 } 653 624 str[pos] = 0; 654 - printf(" %-4s ", str); 625 + 626 + if (name) 627 + printf(" %-7s%4s ", name, in_tx ? "(x)" : ""); 628 + else 629 + printf(" %-11s ", str); 655 630 } 656 631 657 632 struct printer_data {