linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
To: Andi Kleen <andi@firstfloor.org>
Cc: jolsa@kernel.org, namhyung@kernel.org,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Andi Kleen <ak@linux.intel.com>
Subject: Re: [PATCH v4 02/15] perf tools script: Support insn output for normal samples
Date: Fri, 8 Mar 2019 10:37:43 -0300	[thread overview]
Message-ID: <20190308133743.GA26260@kernel.org> (raw)
In-Reply-To: <20190305144758.12397-3-andi@firstfloor.org>

Em Tue, Mar 05, 2019 at 06:47:45AM -0800, Andi Kleen escreveu:
> From: Andi Kleen <ak@linux.intel.com>
> 
> 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
> ...
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> 
> ---
> v2:
> Avoid printing instruction when empty
> Only decode when perf.data file was collected on same architecture

Thanks, applied and added some testing notes comparing the output with
the one from 'perf annotate --stdio2':

commit 2109d7fa73200bc6ff7abe909b5fe821224f98b3
Author: Andi Kleen <ak@linux.intel.com>
Date:   Tue Mar 5 06:47:45 2019 -0800

    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() ]
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 7aab0be5fc5f..7b8e69bbbdfe 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -6,6 +6,7 @@ perf-y += perf_regs.o
 perf-y += group.o
 perf-y += machine.o
 perf-y += event.o
+perf-y += archinsn.o
 
 perf-$(CONFIG_DWARF) += dwarf-regs.o
 perf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c
new file mode 100644
index 000000000000..4237bb2e7fa2
--- /dev/null
+++ b/tools/perf/arch/x86/util/archinsn.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "perf.h"
+#include "archinsn.h"
+#include "util/intel-pt-decoder/insn.h"
+#include "machine.h"
+#include "thread.h"
+#include "symbol.h"
+
+void arch_fetch_insn(struct perf_sample *sample,
+		     struct thread *thread,
+		     struct machine *machine)
+{
+	struct insn insn;
+	int len;
+	bool is64bit = false;
+
+	if (!sample->ip)
+		return;
+	len = thread__memcpy(thread, machine, sample->insn, sample->ip, sizeof(sample->insn), &is64bit);
+	if (len <= 0)
+		return;
+	insn_init(&insn, sample->insn, len, is64bit);
+	insn_get_length(&insn);
+	if (insn_complete(&insn) && insn.length <= len)
+		sample->insn_len = insn.length;
+}
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 @@
 #include "util/time-utils.h"
 #include "util/path.h"
 #include "print_binary.h"
+#include "archinsn.h"
 #include <linux/bitmap.h>
 #include <linux/kernel.h>
 #include <linux/stringify.h>
 #include <linux/time64.h>
+#include <sys/utsname.h>
 #include "asm/bug.h"
 #include "util/mem-events.h"
 #include "util/dump-insn.h"
@@ -63,6 +65,7 @@ static const char		*cpu_list;
 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 static struct perf_stat_config	stat_config;
 static int			max_blocks;
+static bool			native_arch;
 
 unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
 
@@ -1227,6 +1230,12 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
 	return len + dlen;
 }
 
+__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
+			    struct thread *thread __maybe_unused,
+			    struct machine *machine __maybe_unused)
+{
+}
+
 static int perf_sample__fprintf_insn(struct perf_sample *sample,
 				     struct perf_event_attr *attr,
 				     struct thread *thread,
@@ -1234,9 +1243,12 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample,
 {
 	int printed = 0;
 
+	if (sample->insn_len == 0 && native_arch)
+		arch_fetch_insn(sample, thread, machine);
+
 	if (PRINT_FIELD(INSNLEN))
 		printed += fprintf(fp, " ilen: %d", sample->insn_len);
-	if (PRINT_FIELD(INSN)) {
+	if (PRINT_FIELD(INSN) && sample->insn_len) {
 		int i;
 
 		printed += fprintf(fp, " insn:");
@@ -3277,6 +3289,7 @@ int cmd_script(int argc, const char **argv)
 		.set = false,
 		.default_no_sample = true,
 	};
+	struct utsname uts;
 	char *script_path = NULL;
 	const char **__argv;
 	int i, j, err = 0;
@@ -3615,6 +3628,12 @@ int cmd_script(int argc, const char **argv)
 	if (symbol__init(&session->header.env) < 0)
 		goto out_delete;
 
+	uname(&uts);
+	if (!strcmp(uts.machine, session->header.env.arch) ||
+	    (!strcmp(uts.machine, "x86_64") &&
+	     !strcmp(session->header.env.arch, "i386")))
+		native_arch = true;
+
 	script.session = session;
 	script__setup_sample_type(&script);
 
diff --git a/tools/perf/util/archinsn.h b/tools/perf/util/archinsn.h
new file mode 100644
index 000000000000..448cbb6b8d7e
--- /dev/null
+++ b/tools/perf/util/archinsn.h
@@ -0,0 +1,12 @@
+#ifndef INSN_H
+#define INSN_H 1
+
+struct perf_sample;
+struct machine;
+struct thread;
+
+void arch_fetch_insn(struct perf_sample *sample,
+		     struct thread *thread,
+		     struct machine *machine);
+
+#endif

  reply	other threads:[~2019-03-08 13:37 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-05 14:47 Support sample context in perf report Andi Kleen
2019-03-05 14:47 ` [PATCH v4 01/15] perf tools: Add utility function to fetch executable Andi Kleen
2019-03-06 20:53   ` Arnaldo Carvalho de Melo
2019-03-06 21:08     ` Andi Kleen
2019-03-09 19:59   ` [tip:perf/urgent] perf thread: Generalize function to copy from thread addr space from intel-bts code tip-bot for Andi Kleen
2019-03-05 14:47 ` [PATCH v4 02/15] perf tools script: Support insn output for normal samples Andi Kleen
2019-03-08 13:37   ` Arnaldo Carvalho de Melo [this message]
2019-03-22 21:59   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2019-03-05 14:47 ` [PATCH v4 03/15] perf tools script: Filter COMM/FORK/.. events by CPU Andi Kleen
2019-03-06 14:23   ` Adrian Hunter
2019-03-07 11:02     ` Jiri Olsa
2019-03-08 13:39       ` Arnaldo Carvalho de Melo
2019-03-08 15:08         ` Andi Kleen
2019-03-05 14:47 ` [PATCH v4 04/15] perf tools report: Support nano seconds Andi Kleen
2019-03-22 21:59   ` [tip:perf/urgent] perf report: Support output in nanoseconds tip-bot for Andi Kleen
2019-03-05 14:47 ` [PATCH v4 05/15] perf tools report: Parse time quantum Andi Kleen
2019-03-08 13:45   ` Arnaldo Carvalho de Melo
2019-03-08 13:52     ` Arnaldo Carvalho de Melo
2019-03-08 17:39       ` Andi Kleen
2019-03-22 22:01   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2019-03-05 14:47 ` [PATCH v4 06/15] perf tools report: Support time sort key Andi Kleen
2019-03-05 14:47 ` [PATCH v4 07/15] perf tools report: Use less for scripts output Andi Kleen
2019-03-08 13:47   ` Arnaldo Carvalho de Melo
2019-03-09  7:52     ` Feng Tang
2019-03-05 14:47 ` [PATCH v4 08/15] perf tools report: Support running scripts for current time range Andi Kleen
2019-03-05 14:47 ` [PATCH v4 09/15] perf tools report: Support builtin perf script in scripts menu Andi Kleen
2019-03-05 14:47 ` [PATCH v4 10/15] perf tools: Add utility function to print ns time stamps Andi Kleen
2019-03-08 13:51   ` Arnaldo Carvalho de Melo
2019-03-22 22:00   ` [tip:perf/urgent] perf time-utils: Add utility function to print time stamps in nanoseconds tip-bot for Andi Kleen
2019-03-05 14:47 ` [PATCH v4 11/15] perf tools report: Implement browsing of individual samples Andi Kleen
2019-03-05 14:47 ` [PATCH v4 12/15] perf tools: Add some new tips describing the new options Andi Kleen
2019-03-05 14:47 ` [PATCH v4 13/15] perf tools report: Add custom scripts to script menu Andi Kleen
2019-03-05 14:47 ` [PATCH v4 14/15] perf tools script: Add array bound checking to list_scripts Andi Kleen
2019-03-05 14:47 ` [PATCH v4 15/15] perf tools ui: Fix ui popup browser for many entries Andi Kleen
2019-03-07 10:57 ` Support sample context in perf report Jiri Olsa
2019-03-07 16:57   ` Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190308133743.GA26260@kernel.org \
    --to=arnaldo.melo@gmail.com \
    --cc=ak@linux.intel.com \
    --cc=andi@firstfloor.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).