aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2019-03-05 09:47:45 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-11 10:56:02 -0400
commit3ab481a1cfe1511b94e142b648e2c5ade9175ed3 (patch)
treea1762cc52696547662ecb352563aea84d0ce0a09 /tools/perf/builtin-script.c
parentd9c1bb2f6a2157b38e8eb63af437cb22701d31ee (diff)
perf script: Support insn output for normal samples
perf script -F +insn was only working for PT traces because the PT instruction decoder was filling in the insn/insn_len sample attributes. Support it for non PT samples too on x86 using the existing x86 instruction decoder. This adds some extra checking to ensure that we don't try to decode instructions when using perf.data from a different architecture. % perf record -a sleep 1 % perf script -F ip,sym,insn --xed ffffffff811704c9 remote_function movl %eax, 0x18(%rbx) ffffffff8100bb50 intel_bts_enable_local retq ffffffff81048612 native_apic_mem_write movl %esi, -0xa04000(%rdi) ffffffff81048612 native_apic_mem_write movl %esi, -0xa04000(%rdi) ffffffff81048612 native_apic_mem_write movl %esi, -0xa04000(%rdi) ffffffff810f1f79 generic_exec_single xor %eax, %eax ffffffff811704c9 remote_function movl %eax, 0x18(%rbx) ffffffff8100bb34 intel_bts_enable_local movl 0x2000(%rax), %edx ffffffff81048610 native_apic_mem_write mov %edi, %edi ... Committer testing: Before: # perf script -F ip,sym,insn --xed | head -5 ffffffffa4068804 native_write_msr addb %al, (%rax) ffffffffa4068804 native_write_msr addb %al, (%rax) ffffffffa4068804 native_write_msr addb %al, (%rax) ffffffffa4068806 native_write_msr addb %al, (%rax) ffffffffa4068806 native_write_msr addb %al, (%rax) # perf script -F ip,sym,insn --xed | grep -v "addb %al, (%rax)" # After: # perf script -F ip,sym,insn --xed | head -5 ffffffffa4068804 native_write_msr wrmsr ffffffffa4068804 native_write_msr wrmsr ffffffffa4068804 native_write_msr wrmsr ffffffffa4068806 native_write_msr nopl %eax, (%rax,%rax,1) ffffffffa4068806 native_write_msr nopl %eax, (%rax,%rax,1) # perf script -F ip,sym,insn --xed | grep -v "addb %al, (%rax)" | head -5 ffffffffa4068804 native_write_msr wrmsr ffffffffa4068804 native_write_msr wrmsr ffffffffa4068804 native_write_msr wrmsr ffffffffa4068806 native_write_msr nopl %eax, (%rax,%rax,1) ffffffffa4068806 native_write_msr nopl %eax, (%rax,%rax,1) # More examples: # perf script -F ip,sym,insn --xed | grep -v native_write_msr | head ffffffffa416b90e tick_check_broadcast_expired btq %rax, 0x1a5f42a(%rip) ffffffffa4956bd0 nmi_cpu_backtrace pushq %r13 ffffffffa415b95e __hrtimer_next_event_base movq 0x18(%rax), %rdx ffffffffa4956bf3 nmi_cpu_backtrace popq %r12 ffffffffa4171d5c smp_call_function_single pause ffffffffa4956bdd nmi_cpu_backtrace mov %ebp, %r12d ffffffffa4797e4d menu_select cmp $0x190, %rax ffffffffa4171d5c smp_call_function_single pause ffffffffa405a7d8 nmi_cpu_backtrace_handler callq 0xffffffffa4956bd0 ffffffffa4797f7a menu_select shr $0x3, %rax # Which matches the annotate output modulo resolving callqs: # perf annotate --stdio2 nmi_cpu_backtrace_handler Samples: 4 of event 'cycles:ppp', 4000 Hz, Event count (approx.): 35908, [percent: local period] nmi_cpu_backtrace_handler() /lib/modules/5.0.0+/build/vmlinux Percent Disassembly of section .text: ffffffff8105a7d0 <nmi_cpu_backtrace_handler>: nmi_cpu_backtrace_handler(): nmi_trigger_cpumask_backtrace(mask, exclude_self, nmi_raise_cpu_backtrace); } static int nmi_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) { 24.45 → callq __fentry__ if (nmi_cpu_backtrace(regs)) mov %rsi,%rdi 75.55 → callq nmi_cpu_backtrace return NMI_HANDLED; movzbl %al,%eax return NMI_DONE; } ← retq # # perf annotate --stdio2 __hrtimer_next_event_base Samples: 4 of event 'cycles:ppp', 4000 Hz, Event count (approx.): 767977, [percent: local period] __hrtimer_next_event_base() /lib/modules/5.0.0+/build/vmlinux Percent Disassembly of section .text: ffffffff8115b910 <__hrtimer_next_event_base>: __hrtimer_next_event_base(): static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, const struct hrtimer *exclude, unsigned int active, ktime_t expires_next) { → callq __fentry__ <SNIP> 4a: add $0x1,%r14 77.31 mov 0x18(%rax),%rdx shl $0x6,%r14 sub 0x38(%rbx,%r14,1),%rdx if (expires < expires_next) { cmp %r12,%rdx ↓ jge 68 <SNIP> Signed-off-by: Andi Kleen <ak@linux.intel.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/20190305144758.12397-3-andi@firstfloor.org [ Converted fetch_exe() to use the name it ended up having when merged: thread__memcpy() ] [ archinsn.c needs the instruction decoder that is only build when CONFIG_AUXTRACE=y, fix that ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 53f78cf3113f..a5080afd361d 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -29,10 +29,12 @@
29#include "util/time-utils.h" 29#include "util/time-utils.h"
30#include "util/path.h" 30#include "util/path.h"
31#include "print_binary.h" 31#include "print_binary.h"
32#include "archinsn.h"
32#include <linux/bitmap.h> 33#include <linux/bitmap.h>
33#include <linux/kernel.h> 34#include <linux/kernel.h>
34#include <linux/stringify.h> 35#include <linux/stringify.h>
35#include <linux/time64.h> 36#include <linux/time64.h>
37#include <sys/utsname.h>
36#include "asm/bug.h" 38#include "asm/bug.h"
37#include "util/mem-events.h" 39#include "util/mem-events.h"
38#include "util/dump-insn.h" 40#include "util/dump-insn.h"
@@ -63,6 +65,7 @@ static const char *cpu_list;
63static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 65static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
64static struct perf_stat_config stat_config; 66static struct perf_stat_config stat_config;
65static int max_blocks; 67static int max_blocks;
68static bool native_arch;
66 69
67unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; 70unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
68 71
@@ -1227,6 +1230,12 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1227 return len + dlen; 1230 return len + dlen;
1228} 1231}
1229 1232
1233__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
1234 struct thread *thread __maybe_unused,
1235 struct machine *machine __maybe_unused)
1236{
1237}
1238
1230static int perf_sample__fprintf_insn(struct perf_sample *sample, 1239static int perf_sample__fprintf_insn(struct perf_sample *sample,
1231 struct perf_event_attr *attr, 1240 struct perf_event_attr *attr,
1232 struct thread *thread, 1241 struct thread *thread,
@@ -1234,9 +1243,12 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample,
1234{ 1243{
1235 int printed = 0; 1244 int printed = 0;
1236 1245
1246 if (sample->insn_len == 0 && native_arch)
1247 arch_fetch_insn(sample, thread, machine);
1248
1237 if (PRINT_FIELD(INSNLEN)) 1249 if (PRINT_FIELD(INSNLEN))
1238 printed += fprintf(fp, " ilen: %d", sample->insn_len); 1250 printed += fprintf(fp, " ilen: %d", sample->insn_len);
1239 if (PRINT_FIELD(INSN)) { 1251 if (PRINT_FIELD(INSN) && sample->insn_len) {
1240 int i; 1252 int i;
1241 1253
1242 printed += fprintf(fp, " insn:"); 1254 printed += fprintf(fp, " insn:");
@@ -3277,6 +3289,7 @@ int cmd_script(int argc, const char **argv)
3277 .set = false, 3289 .set = false,
3278 .default_no_sample = true, 3290 .default_no_sample = true,
3279 }; 3291 };
3292 struct utsname uts;
3280 char *script_path = NULL; 3293 char *script_path = NULL;
3281 const char **__argv; 3294 const char **__argv;
3282 int i, j, err = 0; 3295 int i, j, err = 0;
@@ -3615,6 +3628,12 @@ int cmd_script(int argc, const char **argv)
3615 if (symbol__init(&session->header.env) < 0) 3628 if (symbol__init(&session->header.env) < 0)
3616 goto out_delete; 3629 goto out_delete;
3617 3630
3631 uname(&uts);
3632 if (!strcmp(uts.machine, session->header.env.arch) ||
3633 (!strcmp(uts.machine, "x86_64") &&
3634 !strcmp(session->header.env.arch, "i386")))
3635 native_arch = true;
3636
3618 script.session = session; 3637 script.session = session;
3619 script__setup_sample_type(&script); 3638 script__setup_sample_type(&script);
3620 3639