All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] perf kvm: Guest Symbol Resolution for powerpc
@ 2016-01-22  5:58 Ravi Bangoria
  2016-01-22  5:58 ` [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample Ravi Bangoria
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Ravi Bangoria @ 2016-01-22  5:58 UTC (permalink / raw)
  To: acme; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao, Ravi Bangoria

'perf kvm {record|report}' is used to record and report the profiled
performance of any workload on a guest. From the host, we can collect
guest kernel statistics which is useful in finding out any contentions
in guest kernel symbols for a certain workload.
This feature is not available on powerpc because 'perf' relies on the
'cycles' event (a PMU event) to profile the guest. However, for powerpc,
this can't be used from the host because the PMUs are controlled by the
guest rather than the host.

Due to this issue, we need a different approach to profile the
workload in the guest. There exists a tracepoint 'kvm_hv:kvm_guest_exit'
in powerpc which is hit whenever any of the threads exit the guest
context. The guest instruction pointer dumped along with this
tracepoint data in the field 'pc', can be used as guest instruction
pointer while postprocessing the trace data to map this IP to symbol
from guest.kallsyms.

However, to have some kind of periodicity, we can't use all the kvm
exits, rather exits which are bound to happen in certain intervals.
HV_DECREMENTER Interrupt forces the threads to exit after an interval
of 10 ms.

This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
exit reason for any kvm exit. If it is HV_DECREMENTER, then the
instruction pointer dumped along with this tracepoint is retrieved and
mapped with the guest kallsyms. So for powerpc, 'perf kvm record' will
record 'kvm_hv:kvm_guest_exit' events instead of cycles.

This patch will enable --guest option for perf kvm {record|report} on
powerpc. Still --host --guest together won't work.

This patch can be considered as a next iteration to RFC patch sent by
Hemant Kumar: https://lkml.org/lkml/2015/6/15/670. Hemant's patch is used
for enabling 'perf kvm report', while I've added code to enable
'perf kvm record' on powerpc.

Patches are developed on acme's perf/core branch.

 * changes in v2)
    - Patch 1,2 are breakdown of v1 patch with little changes
    - Patch 3 is new. It fixes output format of perf kvm report

Before applying patch:
[Note: one needs to run vm with kvm enabled]

  $ ./perf kvm --guestkallsyms=guest.kallsyms --guestmodules=guest.modules record -a
  [ perf record: Captured and wrote 1.530 MB perf.data.guest (28768 samples) ]

  $ ./perf script -i perf.data.guest
   qemu-system-ppc  9688 [000] 842566.451558:          1 cycles:ppp:  c0000000001f2860 .mmap_region ([kernel.kallsyms])
   qemu-system-ppc  9688 [000] 842566.451562:          1 cycles:ppp:  c0000000000a2d68 .kvmppc_do_h_enter ([kernel.kallsyms])
   qemu-system-ppc  9688 [000] 842566.451564:          7 cycles:ppp:  c00000000001f26c .vsx_unavailable_tm ([kernel.kallsyms])
   qemu-system-ppc  9688 [000] 842566.451565:        138 cycles:ppp:  c00000000001f26c .vsx_unavailable_tm ([kernel.kallsyms])
   qemu-system-ppc  9688 [000] 842566.451567:       3128 cycles:ppp:  c0000000000097d8 ._switch ([kernel.kallsyms])
   qemu-system-ppc  9688 [000] 842566.451570:      81568 cycles:ppp:  c0000000000ea8bc .wake_up_new_task ([kernel.kallsyms])
           swapper     0 [004] 842566.451580:          1 cycles:ppp:  c0000000001f2d88 .sys_munmap ([kernel.kallsyms])
           swapper     0 [004] 842566.451583:          1 cycles:ppp:  c00000000001f26c .vsx_unavailable_tm ([kernel.kallsyms])
           swapper     0 [004] 842566.451584:         11 cycles:ppp:  c00000000001f26c .vsx_unavailable_tm ([kernel.kallsyms])
           swapper     0 [004] 842566.451585:        226 cycles:ppp:  c0000000000097d4 ._switch ([kernel.kallsyms])
           swapper     0 [004] 842566.451586:       5664 cycles:ppp:  c00000000000990c resume_kernel ([kernel.kallsyms])
           swapper     0 [004] 842566.451591:     147929 cycles:ppp:  c00000000010a4fc .freeze_set_ops ([kernel.kallsyms])
           swapper     0 [008] 842566.451597:          1 cycles:ppp:  c0000000001f2d98 .sys_munmap ([kernel.kallsyms])
           swapper     0 [008] 842566.451600:          1 cycles:ppp:  c0000000000a2ee0 .kvmppc_do_h_enter ([kernel.kallsyms])
           swapper     0 [008] 842566.451602:         11 cycles:ppp:  c0000000000a2ee0 .kvmppc_do_h_enter ([kernel.kallsyms])
           swapper     0 [008] 842566.451603:        224 cycles:ppp:  c00000000001f274 .vsx_unavailable_tm ([kernel.kallsyms])
           swapper     0 [008] 842566.451604:       5240 cycles:ppp:  c000000000009984 fast_exception_return ([kernel.kallsyms])
           swapper     0 [008] 842566.451608:     134752 cycles:ppp:  c000000000780af4 .inet_diag_handler_get_info ([kernel.kallsyms])
           swapper     0 [012] 842566.451616:          1 cycles:ppp:  c0000000001f2828 .mmap_region ([kernel.kallsyms])
           swapper     0 [012] 842566.451619:          1 cycles:ppp:  c0000000000a2d78 .kvmppc_do_h_enter ([kernel.kallsyms])
           swapper     0 [012] 842566.451620:         11 cycles:ppp:  c00000000001f26c .vsx_unavailable_tm ([kernel.kallsyms])
           swapper     0 [012] 842566.451621:        226 cycles:ppp:  c0000000000097d4 ._switch ([kernel.kallsyms])
           swapper     0 [012] 842566.451623:       5549 cycles:ppp:  c00000000000990c resume_kernel ([kernel.kallsyms])

  $ ./perf kvm --guestkallsyms=guest.kallsyms --guestmodules=guest.modules report --stdio
  # To display the perf.data header info, please use --header/--header-only options.
  #
  #
  # Total Lost Samples: 0
  #
  # Samples: 28K of event 'cycles:ppp'
  # Event count (approx.): 10473529515
  #
  # Overhead  Command  Shared Object  Symbol
  # ........  .......  .............  ......
  #

  #
  # (For a higher level overview, try: perf report --sort comm,dso)
  #
  $

After applying patch:

  $ ./perf kvm --guestkallsyms=guest.kallsyms --guestmodules=guest.modules record -a
  [ perf record: Captured and wrote 11.898 MB perf.data.guest (127299 samples) ]

  $ ./perf script -i perf.data.guest
   qemu-system-ppc  9690 [008] 857043.632783: kvm_hv:kvm_guest_exit: VCPU 12: trap=EXTERNAL pc=0xc00000000057a4f0 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632858: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091b70 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632899: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091a14 msr=0x8000000000001032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632912: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632923: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632941: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091b70 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.632977: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091b70 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633012: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633033: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633053: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633077: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633097: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633109: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633120: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633599: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091b70 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633637: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091a14 msr=0x8000000000001032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633650: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
   qemu-system-ppc  9690 [008] 857043.633661: kvm_hv:kvm_guest_exit: VCPU 12: trap=SYSCALL pc=0xc000000000091924 msr=0x8000000000009032, ceded=0

  $ ./perf kvm  --guestkallsyms=guest.kallsyms --guestmodules=guest.modules report --stdio
  # To display the perf.data header info, please use --header/--header-only options.
  #
  #
  # Total Lost Samples: 0
  #
  # Samples: 127K of event 'kvm_hv:kvm_guest_exit'
  # Event count (approx.): 127299
  #
  # Overhead  Command  Shared Object            Symbol
  # ........  .......  .......................  ................................................
  #
       0.02%  :9690    [guest.kernel.kallsyms]  [g] .plpar_hcall_norets
       0.01%  :9689    [guest.kernel.kallsyms]  [g] .n_tty_write
       0.00%  :9690    [guest.kernel.kallsyms]  [g] .n_tty_write
       0.00%  :9690    [unknown]                [u] 0x00003fff966eb690
       0.00%  :9688    [guest.kernel.kallsyms]  [g] .plpar_hcall_norets
       0.00%  :9689    [guest.kernel.kallsyms]  [g] .plpar_hcall_norets
       0.00%  :9689    [unknown]                [u] 0x00003fff866b8830
       0.00%  :9690    [unknown]                [u] 0x00003fff966eb670
       0.00%  :9687    [guest.kernel.kallsyms]  [g] .n_tty_write
       0.00%  :9689    [guest.kernel.kallsyms]  [g] .__copy_tofrom_user_power7
       0.00%  :9689    [guest.kernel.kallsyms]  [g] ._raw_spin_lock_irqsave
       0.00%  :9689    [guest.kernel.kallsyms]  [g] .queue_work_on
       0.00%  :9690    [guest.kernel.kallsyms]  [g] .flush_to_ldisc
       0.00%  :9690    [guest.kernel.kallsyms]  [g] .plpar_hcall
       0.00%  :9690    [guest.kernel.kallsyms]  [g] fast_exception_return
       0.00%  :9690    [unknown]                [u] 0x00003fff966eb6a0
       0.00%  :9690    [unknown]                [u] 0x00003fff966fd09c
       0.00%  :9687    [guest.kernel.kallsyms]  [g] .__copy_tofrom_user_power7
       0.00%  :9688    [guest.kernel.kallsyms]  [g] ._raw_spin_lock_irqsave
       0.00%  :9688    [guest.kernel.kallsyms]  [g] .n_tty_write
       0.00%  :9688    [guest.kernel.kallsyms]  [g] .plpar_hcall
       0.00%  :9689    [guest.kernel.kallsyms]  [g] .__srcu_read_unlock
       0.00%  :9689    [guest.kernel.kallsyms]  [g] ._raw_spin_lock
       0.00%  :9689    [guest.kernel.kallsyms]  [g] .arch_local_irq_restore

Ravi Bangoria (3):
  perf kvm: Introduce evsel as argument to perf_event__preprocess_sample
  perf kvm: enable record|report feature on powerpc
  perf kvm: Fix output fields instead of 'trace' for perf kvm report on
    powerpc

 tools/perf/arch/powerpc/util/Build |   1 +
 tools/perf/arch/powerpc/util/kvm.c | 134 +++++++++++++++++++++++++++++++++++++
 tools/perf/builtin-annotate.c      |   3 +-
 tools/perf/builtin-diff.c          |   3 +-
 tools/perf/builtin-kvm.c           |  23 +++++--
 tools/perf/builtin-mem.c           |  10 +--
 tools/perf/builtin-report.c        |   3 +-
 tools/perf/builtin-script.c        |   3 +-
 tools/perf/builtin-timechart.c     |   8 ++-
 tools/perf/builtin-top.c           |   3 +-
 tools/perf/builtin.h               |   3 +
 tools/perf/tests/hists_cumulate.c  |   2 +-
 tools/perf/tests/hists_filter.c    |   2 +-
 tools/perf/tests/hists_link.c      |   4 +-
 tools/perf/tests/hists_output.c    |   2 +-
 tools/perf/util/event.c            |  15 ++++-
 tools/perf/util/event.h            |   3 +-
 tools/perf/util/evlist.c           |   9 +++
 tools/perf/util/evlist.h           |   1 +
 tools/perf/util/evsel.c            |   7 ++
 tools/perf/util/evsel.h            |   4 ++
 tools/perf/util/session.c          |   9 +--
 tools/perf/util/util.c             |   5 ++
 tools/perf/util/util.h             |   1 +
 24 files changed, 227 insertions(+), 31 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/kvm.c

--
2.1.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample
  2016-01-22  5:58 [PATCH v2 0/3] perf kvm: Guest Symbol Resolution for powerpc Ravi Bangoria
@ 2016-01-22  5:58 ` Ravi Bangoria
  2016-02-01 20:53   ` Arnaldo Carvalho de Melo
  2016-01-22  5:58 ` [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc Ravi Bangoria
  2016-01-22  5:58 ` [PATCH v2 3/3] perf kvm: Fix output fields instead of 'trace' for perf kvm report " Ravi Bangoria
  2 siblings, 1 reply; 9+ messages in thread
From: Ravi Bangoria @ 2016-01-22  5:58 UTC (permalink / raw)
  To: acme; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao, Ravi Bangoria

This patch changes prototype of perf_event__preprocess_sample() with
additional argument evsel added at last.

This change is required because perf_event__preprocess_sample()
function will use evsel to determine cpumode of samples for powerpc
architecture.

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
changes in v2:
    - Breakdown of v1 patch into two sub patches

 tools/perf/builtin-annotate.c     |  3 ++-
 tools/perf/builtin-diff.c         |  3 ++-
 tools/perf/builtin-mem.c          | 10 ++++++----
 tools/perf/builtin-report.c       |  3 ++-
 tools/perf/builtin-script.c       |  3 ++-
 tools/perf/builtin-timechart.c    |  8 +++++---
 tools/perf/builtin-top.c          |  3 ++-
 tools/perf/tests/hists_cumulate.c |  2 +-
 tools/perf/tests/hists_filter.c   |  2 +-
 tools/perf/tests/hists_link.c     |  4 ++--
 tools/perf/tests/hists_output.c   |  2 +-
 tools/perf/util/event.c           |  3 ++-
 tools/perf/util/event.h           |  3 ++-
 13 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index cc5c126..b488a5c 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -94,7 +94,8 @@ static int process_sample_event(struct perf_tool *tool,
 	struct addr_location al;
 	int ret = 0;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		pr_warning("problem processing %d event, skipping it.\n",
 			   event->header.type);
 		return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 36ccc2b..d2a27fe 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -330,7 +330,8 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
 	struct hists *hists = evsel__hists(evsel);
 	int ret = -1;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		pr_warning("problem processing %d event, skipping it.\n",
 			   event->header.type);
 		return -1;
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 3901700..eb27b49 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -61,13 +61,15 @@ static int
 dump_raw_samples(struct perf_tool *tool,
 		 union perf_event *event,
 		 struct perf_sample *sample,
-		 struct machine *machine)
+		 struct machine *machine,
+		 struct perf_evsel *evsel)
 {
 	struct perf_mem *mem = container_of(tool, struct perf_mem, tool);
 	struct addr_location al;
 	const char *fmt;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		fprintf(stderr, "problem processing %d event, skipping it.\n",
 				event->header.type);
 		return -1;
@@ -111,10 +113,10 @@ out_put:
 static int process_sample_event(struct perf_tool *tool,
 				union perf_event *event,
 				struct perf_sample *sample,
-				struct perf_evsel *evsel __maybe_unused,
+				struct perf_evsel *evsel,
 				struct machine *machine)
 {
-	return dump_raw_samples(tool, event, sample, machine);
+	return dump_raw_samples(tool, event, sample, machine, evsel);
 }
 
 static int report_raw_events(struct perf_mem *mem)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 2bf537f..fa7bbd9 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -151,7 +151,8 @@ static int process_sample_event(struct perf_tool *tool,
 	};
 	int ret = 0;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		pr_debug("problem processing %d event, skipping it.\n",
 			 event->header.type);
 		return -1;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index c691214..4363e8a 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -783,7 +783,8 @@ static int process_sample_event(struct perf_tool *tool,
 		return 0;
 	}
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		pr_err("problem processing %d event, skipping it.\n",
 		       event->header.type);
 		return -1;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index bd7a775..a177396 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -470,7 +470,8 @@ static void sched_switch(struct timechart *tchart, int cpu, u64 timestamp,
 
 static const char *cat_backtrace(union perf_event *event,
 				 struct perf_sample *sample,
-				 struct machine *machine)
+				 struct machine *machine,
+				 struct perf_evsel *evsel)
 {
 	struct addr_location al;
 	unsigned int i;
@@ -489,7 +490,8 @@ static const char *cat_backtrace(union perf_event *event,
 	if (!chain)
 		goto exit;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0) {
 		fprintf(stderr, "problem processing %d event, skipping it.\n",
 			event->header.type);
 		goto exit;
@@ -569,7 +571,7 @@ static int process_sample_event(struct perf_tool *tool,
 	if (evsel->handler != NULL) {
 		tracepoint_handler f = evsel->handler;
 		return f(tchart, evsel, sample,
-			 cat_backtrace(event, sample, machine));
+			 cat_backtrace(event, sample, machine, evsel));
 	}
 
 	return 0;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index bf01cbb..3d10ce3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -726,7 +726,8 @@ static void perf_event__process_sample(struct perf_tool *tool,
 	if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
 		top->exact_samples++;
 
-	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0)
+	if (perf_event__preprocess_sample(event, machine, &al,
+					  sample, evsel) < 0)
 		return;
 
 	if (!top->kptr_restrict_warned &&
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index 5e6a86e..24bbde9 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -103,7 +103,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
 		sample.callchain = (struct ip_callchain *)fake_callchains[i];
 
 		if (perf_event__preprocess_sample(&event, machine, &al,
-						  &sample) < 0)
+						  &sample, evsel) < 0)
 			goto out;
 
 		if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index 351a424..3fb4022 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -81,7 +81,7 @@ static int add_hist_entries(struct perf_evlist *evlist,
 			sample.ip = fake_samples[i].ip;
 
 			if (perf_event__preprocess_sample(&event, machine, &al,
-							  &sample) < 0)
+							  &sample, evsel) < 0)
 				goto out;
 
 			al.socket = fake_samples[i].socket;
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 64b257d..7b8c590 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -86,7 +86,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 			sample.tid = fake_common_samples[k].pid;
 			sample.ip = fake_common_samples[k].ip;
 			if (perf_event__preprocess_sample(&event, machine, &al,
-							  &sample) < 0)
+							  &sample, evsel) < 0)
 				goto out;
 
 			he = __hists__add_entry(hists, &al, NULL,
@@ -112,7 +112,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 			sample.tid = fake_samples[i][k].pid;
 			sample.ip = fake_samples[i][k].ip;
 			if (perf_event__preprocess_sample(&event, machine, &al,
-							  &sample) < 0)
+							  &sample, evsel) < 0)
 				goto out;
 
 			he = __hists__add_entry(hists, &al, NULL,
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c
index b231265..82a7c61 100644
--- a/tools/perf/tests/hists_output.c
+++ b/tools/perf/tests/hists_output.c
@@ -69,7 +69,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
 		sample.ip = fake_samples[i].ip;
 
 		if (perf_event__preprocess_sample(&event, machine, &al,
-						  &sample) < 0)
+						  &sample, evsel) < 0)
 			goto out;
 
 		if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 85155e9..f86e172 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1298,7 +1298,8 @@ void thread__find_addr_location(struct thread *thread,
 int perf_event__preprocess_sample(const union perf_event *event,
 				  struct machine *machine,
 				  struct addr_location *al,
-				  struct perf_sample *sample)
+				  struct perf_sample *sample,
+				  struct perf_evsel *evsel)
 {
 	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 	struct thread *thread = machine__findnew_thread(machine, sample->pid,
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index b7ffb7e..fb8489b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -600,7 +600,8 @@ struct addr_location;
 int perf_event__preprocess_sample(const union perf_event *event,
 				  struct machine *machine,
 				  struct addr_location *al,
-				  struct perf_sample *sample);
+				  struct perf_sample *sample,
+				  struct perf_evsel *evsel);
 
 void addr_location__put(struct addr_location *al);
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc
  2016-01-22  5:58 [PATCH v2 0/3] perf kvm: Guest Symbol Resolution for powerpc Ravi Bangoria
  2016-01-22  5:58 ` [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample Ravi Bangoria
@ 2016-01-22  5:58 ` Ravi Bangoria
  2016-02-01 21:06   ` Arnaldo Carvalho de Melo
  2016-01-22  5:58 ` [PATCH v2 3/3] perf kvm: Fix output fields instead of 'trace' for perf kvm report " Ravi Bangoria
  2 siblings, 1 reply; 9+ messages in thread
From: Ravi Bangoria @ 2016-01-22  5:58 UTC (permalink / raw)
  To: acme; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao, Ravi Bangoria

This patch contains core logic for enabling perf kvm {record|report} on
powerpc.

For perf kvm record,
This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
while recording guest data from host.

For perf kvm report,
This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
exit reason for any kvm exit. If it is HV_DECREMENTER, then the
instruction pointer dumped along with this tracepoint is retrieved and
mapped with the guest kallsyms.

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
---
changes in v2:
    - Breakdown of v1 patch into two sub patches
    - Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
      single file with name kvm.c

 tools/perf/arch/powerpc/util/Build |   1 +
 tools/perf/arch/powerpc/util/kvm.c | 104 +++++++++++++++++++++++++++++++++++++
 tools/perf/util/event.c            |  12 ++++-
 tools/perf/util/evlist.c           |   9 ++++
 tools/perf/util/evlist.h           |   1 +
 tools/perf/util/evsel.c            |   7 +++
 tools/perf/util/evsel.h            |   4 ++
 tools/perf/util/session.c          |   9 ++--
 tools/perf/util/util.c             |   5 ++
 tools/perf/util/util.h             |   1 +
 10 files changed, 147 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/kvm.c

diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build
index 7b8b0d1..eb819e0 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -1,5 +1,6 @@
 libperf-y += header.o
 libperf-y += sym-handling.o
+libperf-y += kvm.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
diff --git a/tools/perf/arch/powerpc/util/kvm.c b/tools/perf/arch/powerpc/util/kvm.c
new file mode 100644
index 0000000..317f29a
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/kvm.c
@@ -0,0 +1,104 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
+ * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
+ */
+
+#include <linux/err.h>
+#include "../../../util/evsel.h"
+#include "../../../util/evlist.h"
+#include "../../../util/trace-event.h"
+#include "../../../util/session.h"
+#include "../../../util/util.h"
+
+#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
+#define HV_DECREMENTER 2432
+#define HV_BIT 3
+#define PR_BIT 49
+#define PPC_MAX 63
+
+/*
+ * To sample for only guest, record kvm_hv:kvm_guest_exit.
+ * Otherwise go via normal way(cycles).
+ */
+int perf_evlist__arch_add_default(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+
+	if (!perf_guest_only())
+		return -1;
+
+	evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
+	if (IS_ERR(evsel))
+		return PTR_ERR(evsel);
+
+	perf_evlist__add(evlist, evsel);
+	return 0;
+}
+
+static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
+{
+	static unsigned int kvmppc_exit;
+
+	if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
+		return false;
+
+	if (unlikely(kvmppc_exit == 0)) {
+		if (strcmp(KVMPPC_EXIT, evsel->name))
+			return false;
+		kvmppc_exit = evsel->attr.config;
+	} else if (kvmppc_exit != evsel->attr.config) {
+		return false;
+	}
+
+	return true;
+}
+
+static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample *sample)
+{
+	int trap = perf_evsel__intval(evsel, sample, "trap");
+	return trap == HV_DECREMENTER;
+}
+
+/*
+ * Get the instruction pointer from the tracepoint data
+ */
+u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
+{
+	if (perf_guest_only() &&
+	    is_kvmppc_exit_event(evsel) &&
+	    is_hv_dec_trap(evsel, sample))
+		return perf_evsel__intval(evsel, sample, "pc");
+
+	return sample->ip;
+}
+
+/*
+ * Get the HV and PR bits and accordingly, determine the cpumode
+ */
+u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
+		     struct perf_sample *sample)
+{
+	unsigned long hv, pr, msr;
+	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+	if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
+		goto ret;
+
+	if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
+		msr = perf_evsel__intval(evsel, sample, "msr");
+		hv = msr & ((unsigned long)1 << (PPC_MAX - HV_BIT));
+		pr = msr & ((unsigned long)1 << (PPC_MAX - PR_BIT));
+
+		if (!hv && pr)
+			cpumode = PERF_RECORD_MISC_GUEST_USER;
+		else
+			cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
+	}
+
+ret:
+	return cpumode;
+}
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f86e172..b8105a6 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1291,6 +1291,13 @@ void thread__find_addr_location(struct thread *thread,
 		al->sym = NULL;
 }
 
+u8 __weak arch__get_cpumode(const union perf_event *event,
+			    struct perf_evsel *evsel __maybe_unused,
+			    struct perf_sample *sample __maybe_unused)
+{
+	return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
@@ -1301,13 +1308,14 @@ int perf_event__preprocess_sample(const union perf_event *event,
 				  struct perf_sample *sample,
 				  struct perf_evsel *evsel)
 {
-	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+	u8 cpumode;
 	struct thread *thread = machine__findnew_thread(machine, sample->pid,
 							sample->tid);
-
 	if (thread == NULL)
 		return -1;
 
+	al->cpumode = cpumode = arch__get_cpumode(event, evsel, sample);
+
 	dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
 	/*
 	 * Have we already created the kernel maps for this machine?
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d81f13d..d0dca72 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -231,6 +231,12 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr)
 	}
 }
 
+int __weak
+perf_evlist__arch_add_default(struct perf_evlist *evlist __maybe_unused)
+{
+	return -1;
+}
+
 int perf_evlist__add_default(struct perf_evlist *evlist)
 {
 	struct perf_event_attr attr = {
@@ -239,6 +245,9 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
 	};
 	struct perf_evsel *evsel;
 
+	if (!perf_evlist__arch_add_default(evlist))
+		return 0;
+
 	event_attr_init(&attr);
 
 	perf_event_attr__set_max_precise_ip(&attr);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 7c4d9a2..98e24cd 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -75,6 +75,7 @@ void perf_evlist__delete(struct perf_evlist *evlist);
 
 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
 void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel);
+int perf_evlist__arch_add_default(struct perf_evlist *evlist);
 int perf_evlist__add_default(struct perf_evlist *evlist);
 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
 				     struct perf_event_attr *attrs, size_t nr_attrs);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 4678086..afe1091 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1607,6 +1607,12 @@ static inline bool overflow(const void *endp, u16 max_size, const void *offset,
 #define OVERFLOW_CHECK_u64(offset) \
 	OVERFLOW_CHECK(offset, sizeof(u64), sizeof(u64))
 
+u64 __weak arch__get_ip(struct perf_evsel *evsel __maybe_unused,
+			struct perf_sample *sample)
+{
+	return sample->ip;
+}
+
 int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 			     struct perf_sample *data)
 {
@@ -1780,6 +1786,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 		OVERFLOW_CHECK(array, data->raw_size, max_size);
 		data->raw_data = (void *)array;
 		array = (void *)array + data->raw_size;
+		data->ip = arch__get_ip(evsel, data);
 	}
 
 	if (type & PERF_SAMPLE_BRANCH_STACK) {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8e75434..eb6f52e 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -400,4 +400,8 @@ typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *);
 int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
 			     attr__fprintf_f attr__fprintf, void *priv);
 
+u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample);
+u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
+		     struct perf_sample *sample);
+
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 40b7a0d..1081ee0 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1130,10 +1130,11 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
 }
 
 static struct machine *machines__find_for_cpumode(struct machines *machines,
-					       union perf_event *event,
-					       struct perf_sample *sample)
+						  union perf_event *event,
+						  struct perf_sample *sample,
+						  struct perf_evsel *evsel)
 {
-	const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+	u8 cpumode = arch__get_cpumode(event, evsel, sample);
 	struct machine *machine;
 
 	if (perf_guest &&
@@ -1237,7 +1238,7 @@ static int machines__deliver_event(struct machines *machines,
 
 	evsel = perf_evlist__id2evsel(evlist, sample->id);
 
-	machine = machines__find_for_cpumode(machines, event, sample);
+	machine = machines__find_for_cpumode(machines, event, sample, evsel);
 
 	switch (event->header.type) {
 	case PERF_RECORD_SAMPLE:
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 7a2da7e..5e48ef1 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -37,6 +37,11 @@ bool test_attr__enabled;
 bool perf_host  = true;
 bool perf_guest = false;
 
+bool perf_guest_only(void)
+{
+	return !perf_host && perf_guest;
+}
+
 void event_attr_init(struct perf_event_attr *attr)
 {
 	if (!perf_host)
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 61650f0..eff1d8f 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -344,5 +344,6 @@ int fetch_kernel_version(unsigned int *puint,
 
 const char *perf_tip(const char *dirpath);
 bool is_regular_file(const char *file);
+bool perf_guest_only(void);
 
 #endif /* GIT_COMPAT_UTIL_H */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] perf kvm: Fix output fields instead of 'trace' for perf kvm report on powerpc
  2016-01-22  5:58 [PATCH v2 0/3] perf kvm: Guest Symbol Resolution for powerpc Ravi Bangoria
  2016-01-22  5:58 ` [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample Ravi Bangoria
  2016-01-22  5:58 ` [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc Ravi Bangoria
@ 2016-01-22  5:58 ` Ravi Bangoria
  2 siblings, 0 replies; 9+ messages in thread
From: Ravi Bangoria @ 2016-01-22  5:58 UTC (permalink / raw)
  To: acme; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao, Ravi Bangoria

commit d49dadea7862 ("perf tools: Make 'trace' or 'trace_fields' sort key
default for tracepoint events") makes 'trace' sort key as a default
while displaying report for tracepoint.

As tracepoint(kvm_hv:kvm_guest_exit) is used as a default event for
recording data, perf kvm report will display output as a list of
tracepoint hits and not with a normal report columns.

This patch will replace 'overhead,comm,dso,sym' fields instead of 'trace'
while displaying perf kvm report on powerpc.

Before applying patch:

  $ ./perf kvm --guestkallsyms=guest.kallsyms --guestmodules=guest.modules report --stdio
  # To display the perf.data header info, please use --header/--header-only options.
  #
  #
  # Total Lost Samples: 0
  #
  # Samples: 181K of event 'kvm_hv:kvm_guest_exit'
  # Event count (approx.): 181061
  #
  # Overhead  Trace output
  # ........  .................................................................................
  #
       0.02%  VCPU 8: trap=HV_DECREMENTER pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
       0.00%  VCPU 0: trap=HV_DECREMENTER pc=0xc000000000091924 msr=0x8000000000009032, ceded=0
       0.00%  VCPU 8: trap=HV_DECREMENTER pc=0x10005c7c msr=0x800000000280f032, ceded=0
       0.00%  VCPU 8: trap=HV_DECREMENTER pc=0x1001ef14 msr=0x800000000280f032, ceded=0
       0.00%  VCPU 8: trap=HV_DECREMENTER pc=0x3fff83398830 msr=0x800000000280f032, ceded=0
       0.00%  VCPU 8: trap=HV_DECREMENTER pc=0x3fff833a6fe4 msr=0x800000000280f032, ceded=0
       0.00%  VCPU 8: trap=HV_DECREMENTER pc=0x3fff833a7a64 msr=0x800000000280f032, ceded=0

After applying patch:

  $ ./perf kvm --guestkallsyms=guest.kallsyms --guestmodules=guest.modules report --stdio
  # To display the perf.data header info, please use --header/--header-only options.
  #
  #
  # Total Lost Samples: 0
  #
  # Samples: 181K of event 'kvm_hv:kvm_guest_exit'
  # Event count (approx.): 181061
  #
  # Overhead  Command  Shared Object            Symbol
  # ........  .......  .......................  ..............................
  #
       0.02%  :57276   [guest.kernel.kallsyms]  [g] .plpar_hcall_norets
       0.00%  :57274   [guest.kernel.kallsyms]  [g] .plpar_hcall_norets
       0.00%  :57276   [guest.kernel.kallsyms]  [g] .__copy_tofrom_user_power7
       0.00%  :57276   [guest.kernel.kallsyms]  [g] ._atomic_dec_and_lock
       0.00%  :57276   [guest.kernel.kallsyms]  [g] ._raw_spin_lock
       0.00%  :57276   [guest.kernel.kallsyms]  [g] ._switch
       0.00%  :57276   [guest.kernel.kallsyms]  [g] .bio_add_page
       0.00%  :57276   [guest.kernel.kallsyms]  [g] .kmem_cache_alloc

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
changes in v2:
    - Fixes output format of perf kvm report on powerpc

 tools/perf/arch/powerpc/util/kvm.c | 30 ++++++++++++++++++++++++++++++
 tools/perf/builtin-kvm.c           | 23 +++++++++++++++++------
 tools/perf/builtin.h               |  3 +++
 3 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/kvm.c b/tools/perf/arch/powerpc/util/kvm.c
index 317f29a..e5d88cc 100644
--- a/tools/perf/arch/powerpc/util/kvm.c
+++ b/tools/perf/arch/powerpc/util/kvm.c
@@ -8,11 +8,13 @@
  */
 
 #include <linux/err.h>
+#include <string.h>
 #include "../../../util/evsel.h"
 #include "../../../util/evlist.h"
 #include "../../../util/trace-event.h"
 #include "../../../util/session.h"
 #include "../../../util/util.h"
+#include "../../../builtin.h"
 
 #define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
 #define HV_DECREMENTER 2432
@@ -102,3 +104,31 @@ u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
 ret:
 	return cpumode;
 }
+
+const char **arch__cmd_kvm_report_argv(const char *file_name, int argc,
+				       int *rec_argc, const char **argv)
+{
+	int i = 0, j, arch_argc = 0;
+	const char **rec_argv;
+
+	if (perf_guest_only())
+		arch_argc = 2;
+
+	*rec_argc = argc + arch_argc + 2;
+	rec_argv = calloc(*rec_argc + 1, sizeof(char *));
+	rec_argv[i++] = strdup("report");
+	rec_argv[i++] = strdup("-i");
+	rec_argv[i++] = strdup(file_name);
+
+	if (arch_argc) {
+		rec_argv[i++] = strdup("-F");
+		rec_argv[i++] = strdup("overhead,comm,dso,sym");
+	}
+
+	for (j = 1; j < argc; j++, i++)
+		rec_argv[i] = argv[j];
+
+	BUG_ON(i != *rec_argc);
+
+	return rec_argv;
+}
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 4418d92..48455c9 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1480,22 +1480,33 @@ static int __cmd_record(const char *file_name, int argc, const char **argv)
 	return cmd_record(i, rec_argv, NULL);
 }
 
-static int __cmd_report(const char *file_name, int argc, const char **argv)
+
+const char ** __weak arch__cmd_kvm_report_argv(const char *file_name, int argc,
+					       int *rec_argc, const char **argv)
 {
-	int rec_argc, i = 0, j;
+	int i = 0, j;
 	const char **rec_argv;
 
-	rec_argc = argc + 2;
-	rec_argv = calloc(rec_argc + 1, sizeof(char *));
+	*rec_argc = argc + 2;
+	rec_argv = calloc(*rec_argc + 1, sizeof(char *));
 	rec_argv[i++] = strdup("report");
 	rec_argv[i++] = strdup("-i");
 	rec_argv[i++] = strdup(file_name);
 	for (j = 1; j < argc; j++, i++)
 		rec_argv[i] = argv[j];
 
-	BUG_ON(i != rec_argc);
+	BUG_ON(i != *rec_argc);
+
+	return rec_argv;
+}
+
+static int __cmd_report(const char *file_name, int argc, const char **argv)
+{
+	int rec_argc;
+	const char **rec_argv = arch__cmd_kvm_report_argv(file_name, argc,
+							  &rec_argc, argv);
 
-	return cmd_report(i, rec_argv, NULL);
+	return cmd_report(rec_argc, rec_argv, NULL);
 }
 
 static int
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 3f871b5..2ac149b 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -41,4 +41,7 @@ extern int cmd_mem(int argc, const char **argv, const char *prefix);
 extern int cmd_data(int argc, const char **argv, const char *prefix);
 
 extern int find_scripts(char **scripts_array, char **scripts_path_array);
+
+extern const char **arch__cmd_kvm_report_argv(const char *file_name,
+			int argc, int *rec_argc, const char **argv);
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample
  2016-01-22  5:58 ` [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample Ravi Bangoria
@ 2016-02-01 20:53   ` Arnaldo Carvalho de Melo
  2016-02-02  9:07     ` Ravi Bangoria
  0 siblings, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-02-01 20:53 UTC (permalink / raw)
  To: Ravi Bangoria; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao

Em Fri, Jan 22, 2016 at 11:28:10AM +0530, Ravi Bangoria escreveu:
> This patch changes prototype of perf_event__preprocess_sample() with
> additional argument evsel added at last.
> 
> This change is required because perf_event__preprocess_sample()
> function will use evsel to determine cpumode of samples for powerpc
> architecture.
> 
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>

Fixing these problems:



  CC       /tmp/build/perf/ui/gtk/util.o
util/event.c: In function ‘perf_event__preprocess_sample’:
util/event.c:1302:26: error: unused parameter ‘evsel’ [-Werror=unused-parameter]
       struct perf_evsel *evsel)
                          ^
cc1: all warnings being treated as errors
mv: cannot stat ‘/tmp/build/perf/util/.event.o.tmp’: No such file or directory
/home/acme/git/linux/tools/build/Makefile.build:77: recipe for target '/tmp/build/perf/util/event.o' failed
make[3]: *** [/tmp/build/perf/util/event.o] Error 1
make[3]: *** Waiting for unfinished jobs....
  CC       /tmp/build/perf/ui/gtk/helpline.o
  CC       /tmp/build/perf/arch/common.o
/home/acme/git/linux/tools/build/Makefile.build:116: recipe for target 'util' failed
make[2]: *** [util] Error 2
make[2]: *** Waiting for unfinished jobs....

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc
  2016-01-22  5:58 ` [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc Ravi Bangoria
@ 2016-02-01 21:06   ` Arnaldo Carvalho de Melo
  2016-02-02  9:06     ` Ravi Bangoria
  0 siblings, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-02-01 21:06 UTC (permalink / raw)
  To: Ravi Bangoria; +Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao

Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:
> This patch contains core logic for enabling perf kvm {record|report} on
> powerpc.
> 
> For perf kvm record,
> This patch will replace default event(cycle) with kvm_hv:kvm_guest_exit
> while recording guest data from host.
> 
> For perf kvm report,
> This patch makes use of the 'kvm_guest_exit' tracepoint and checks the
> exit reason for any kvm exit. If it is HV_DECREMENTER, then the
> instruction pointer dumped along with this tracepoint is retrieved and
> mapped with the guest kallsyms.
> 
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
> ---
> changes in v2:
>     - Breakdown of v1 patch into two sub patches
>     - Merged parse-tp.c and evlist.c from tools/perf/arch/powerpc/util/ into
>       single file with name kvm.c
> 
>  tools/perf/arch/powerpc/util/Build |   1 +
>  tools/perf/arch/powerpc/util/kvm.c | 104 +++++++++++++++++++++++++++++++++++++
>  tools/perf/util/event.c            |  12 ++++-
>  tools/perf/util/evlist.c           |   9 ++++
>  tools/perf/util/evlist.h           |   1 +
>  tools/perf/util/evsel.c            |   7 +++
>  tools/perf/util/evsel.h            |   4 ++
>  tools/perf/util/session.c          |   9 ++--
>  tools/perf/util/util.c             |   5 ++
>  tools/perf/util/util.h             |   1 +
>  10 files changed, 147 insertions(+), 6 deletions(-)
>  create mode 100644 tools/perf/arch/powerpc/util/kvm.c
> 
> diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build
> index 7b8b0d1..eb819e0 100644
> --- a/tools/perf/arch/powerpc/util/Build
> +++ b/tools/perf/arch/powerpc/util/Build
> @@ -1,5 +1,6 @@
>  libperf-y += header.o
>  libperf-y += sym-handling.o
> +libperf-y += kvm.o
>  
>  libperf-$(CONFIG_DWARF) += dwarf-regs.o
>  libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
> diff --git a/tools/perf/arch/powerpc/util/kvm.c b/tools/perf/arch/powerpc/util/kvm.c
> new file mode 100644
> index 0000000..317f29a
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/util/kvm.c
> @@ -0,0 +1,104 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation.
> + *
> + * Copyright (C) 2016 Hemant Kumar Shaw, IBM Corporation
> + * Copyright (C) 2016 Ravikumar B. Bangoria, IBM Corporation
> + */
> +
> +#include <linux/err.h>
> +#include "../../../util/evsel.h"
> +#include "../../../util/evlist.h"
> +#include "../../../util/trace-event.h"
> +#include "../../../util/session.h"
> +#include "../../../util/util.h"
> +
> +#define KVMPPC_EXIT "kvm_hv:kvm_guest_exit"
> +#define HV_DECREMENTER 2432
> +#define HV_BIT 3
> +#define PR_BIT 49
> +#define PPC_MAX 63
> +
> +/*
> + * To sample for only guest, record kvm_hv:kvm_guest_exit.
> + * Otherwise go via normal way(cycles).
> + */
> +int perf_evlist__arch_add_default(struct perf_evlist *evlist)
> +{
> +	struct perf_evsel *evsel;
> +
> +	if (!perf_guest_only())
> +		return -1;
> +
> +	evsel = perf_evsel__newtp_idx("kvm_hv", "kvm_guest_exit", 0);
> +	if (IS_ERR(evsel))
> +		return PTR_ERR(evsel);
> +
> +	perf_evlist__add(evlist, evsel);
> +	return 0;
> +}
> +
> +static bool is_kvmppc_exit_event(struct perf_evsel *evsel)
> +{
> +	static unsigned int kvmppc_exit;
> +
> +	if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
> +		return false;
> +
> +	if (unlikely(kvmppc_exit == 0)) {
> +		if (strcmp(KVMPPC_EXIT, evsel->name))
> +			return false;
> +		kvmppc_exit = evsel->attr.config;
> +	} else if (kvmppc_exit != evsel->attr.config) {
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
> +static bool is_hv_dec_trap(struct perf_evsel *evsel, struct perf_sample *sample)
> +{
> +	int trap = perf_evsel__intval(evsel, sample, "trap");
> +	return trap == HV_DECREMENTER;
> +}
> +
> +/*
> + * Get the instruction pointer from the tracepoint data
> + */
> +u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample)
> +{
> +	if (perf_guest_only() &&
> +	    is_kvmppc_exit_event(evsel) &&
> +	    is_hv_dec_trap(evsel, sample))
> +		return perf_evsel__intval(evsel, sample, "pc");
> +
> +	return sample->ip;
> +}
> +
> +/*
> + * Get the HV and PR bits and accordingly, determine the cpumode
> + */
> +u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
> +		     struct perf_sample *sample)
> +{
> +	unsigned long hv, pr, msr;
> +	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +
> +	if (!perf_guest_only() || !is_kvmppc_exit_event(evsel))
> +		goto ret;
> +
> +	if (sample->raw_data && is_hv_dec_trap(evsel, sample)) {
> +		msr = perf_evsel__intval(evsel, sample, "msr");
> +		hv = msr & ((unsigned long)1 << (PPC_MAX - HV_BIT));
> +		pr = msr & ((unsigned long)1 << (PPC_MAX - PR_BIT));
> +
> +		if (!hv && pr)
> +			cpumode = PERF_RECORD_MISC_GUEST_USER;
> +		else
> +			cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
> +	}
> +
> +ret:
> +	return cpumode;
> +}
> diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
> index f86e172..b8105a6 100644
> --- a/tools/perf/util/event.c
> +++ b/tools/perf/util/event.c
> @@ -1291,6 +1291,13 @@ void thread__find_addr_location(struct thread *thread,
>  		al->sym = NULL;
>  }
>  
> +u8 __weak arch__get_cpumode(const union perf_event *event,
> +			    struct perf_evsel *evsel __maybe_unused,
> +			    struct perf_sample *sample __maybe_unused)
> +{
> +	return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +}

This hunk and the next should be on the previous patch, that is not even
compiling...

You have to compile patch by patch, we can't just test at the end of a
patchkit like this, this destroys bisection ;-\

Also you first need to put in place a way to override how to obtain the
cpumode, then you should use it.

Also this mode doesn't look feasible at all, think about processing
perf.data files generated in !powerpc systems being analysed in a
powerpc system. This has to be dependend on the architecture of the
machine where the perf.data file was recorded, not on the archictecture
of the machine the binary was built for.

It is only when you do live analysis, like with 'perf trace' and 'perf
top' that its guaranteed to be all on the same machine.

IIRC in one of the patches in this series you introduce and use a
library function on the same patch, please break it into two patches as
well, lemme see what is the name...

Yeah, it is also in this patch:

perf_evlist__arch_add_default(struct perf_evlist *evlist)

Please add this in a separate patch, stating in the changeset comment
why it is needed and how architectures can override it.

- Arnaldo

> +
>  /*
>   * Callers need to drop the reference to al->thread, obtained in
>   * machine__findnew_thread()
> @@ -1301,13 +1308,14 @@ int perf_event__preprocess_sample(const union perf_event *event,
>  				  struct perf_sample *sample,
>  				  struct perf_evsel *evsel)
>  {
> -	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +	u8 cpumode;
>  	struct thread *thread = machine__findnew_thread(machine, sample->pid,
>  							sample->tid);
> -
>  	if (thread == NULL)
>  		return -1;
>  
> +	al->cpumode = cpumode = arch__get_cpumode(event, evsel, sample);
> +
>  	dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
>  	/*
>  	 * Have we already created the kernel maps for this machine?
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index d81f13d..d0dca72 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -231,6 +231,12 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr)
>  	}
>  }
>  
> +int __weak
> +perf_evlist__arch_add_default(struct perf_evlist *evlist __maybe_unused)
> +{
> +	return -1;
> +}
> +
>  int perf_evlist__add_default(struct perf_evlist *evlist)
>  {
>  	struct perf_event_attr attr = {
> @@ -239,6 +245,9 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
>  	};
>  	struct perf_evsel *evsel;
>  
> +	if (!perf_evlist__arch_add_default(evlist))
> +		return 0;
> +
>  	event_attr_init(&attr);
>  
>  	perf_event_attr__set_max_precise_ip(&attr);
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index 7c4d9a2..98e24cd 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -75,6 +75,7 @@ void perf_evlist__delete(struct perf_evlist *evlist);
>  
>  void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
>  void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel);
> +int perf_evlist__arch_add_default(struct perf_evlist *evlist);
>  int perf_evlist__add_default(struct perf_evlist *evlist);
>  int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
>  				     struct perf_event_attr *attrs, size_t nr_attrs);
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 4678086..afe1091 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -1607,6 +1607,12 @@ static inline bool overflow(const void *endp, u16 max_size, const void *offset,
>  #define OVERFLOW_CHECK_u64(offset) \
>  	OVERFLOW_CHECK(offset, sizeof(u64), sizeof(u64))
>  
> +u64 __weak arch__get_ip(struct perf_evsel *evsel __maybe_unused,
> +			struct perf_sample *sample)
> +{
> +	return sample->ip;
> +}
> +
>  int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
>  			     struct perf_sample *data)
>  {
> @@ -1780,6 +1786,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
>  		OVERFLOW_CHECK(array, data->raw_size, max_size);
>  		data->raw_data = (void *)array;
>  		array = (void *)array + data->raw_size;
> +		data->ip = arch__get_ip(evsel, data);
>  	}
>  
>  	if (type & PERF_SAMPLE_BRANCH_STACK) {
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 8e75434..eb6f52e 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -400,4 +400,8 @@ typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *);
>  int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
>  			     attr__fprintf_f attr__fprintf, void *priv);
>  
> +u64 arch__get_ip(struct perf_evsel *evsel, struct perf_sample *sample);
> +u8 arch__get_cpumode(const union perf_event *event, struct perf_evsel *evsel,
> +		     struct perf_sample *sample);
> +
>  #endif /* __PERF_EVSEL_H */
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 40b7a0d..1081ee0 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -1130,10 +1130,11 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
>  }
>  
>  static struct machine *machines__find_for_cpumode(struct machines *machines,
> -					       union perf_event *event,
> -					       struct perf_sample *sample)
> +						  union perf_event *event,
> +						  struct perf_sample *sample,
> +						  struct perf_evsel *evsel)
>  {
> -	const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
> +	u8 cpumode = arch__get_cpumode(event, evsel, sample);
>  	struct machine *machine;
>  
>  	if (perf_guest &&
> @@ -1237,7 +1238,7 @@ static int machines__deliver_event(struct machines *machines,
>  
>  	evsel = perf_evlist__id2evsel(evlist, sample->id);
>  
> -	machine = machines__find_for_cpumode(machines, event, sample);
> +	machine = machines__find_for_cpumode(machines, event, sample, evsel);
>  
>  	switch (event->header.type) {
>  	case PERF_RECORD_SAMPLE:
> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
> index 7a2da7e..5e48ef1 100644
> --- a/tools/perf/util/util.c
> +++ b/tools/perf/util/util.c
> @@ -37,6 +37,11 @@ bool test_attr__enabled;
>  bool perf_host  = true;
>  bool perf_guest = false;
>  
> +bool perf_guest_only(void)
> +{
> +	return !perf_host && perf_guest;
> +}
> +
>  void event_attr_init(struct perf_event_attr *attr)
>  {
>  	if (!perf_host)
> diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
> index 61650f0..eff1d8f 100644
> --- a/tools/perf/util/util.h
> +++ b/tools/perf/util/util.h
> @@ -344,5 +344,6 @@ int fetch_kernel_version(unsigned int *puint,
>  
>  const char *perf_tip(const char *dirpath);
>  bool is_regular_file(const char *file);
> +bool perf_guest_only(void);
>  
>  #endif /* GIT_COMPAT_UTIL_H */
> -- 
> 2.1.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc
  2016-02-01 21:06   ` Arnaldo Carvalho de Melo
@ 2016-02-02  9:06     ` Ravi Bangoria
  2016-02-09 10:47       ` Ravi Bangoria
  0 siblings, 1 reply; 9+ messages in thread
From: Ravi Bangoria @ 2016-02-02  9:06 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao

HI acme,

On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:
> Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:
>> +	return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
>> +}
> This hunk and the next should be on the previous patch, that is not even
> compiling...
>
> You have to compile patch by patch, we can't just test at the end of a
> patchkit like this, this destroys bisection ;-\

Didn't aware about that. Will take care of compiling each patch
separately next time onwards.

> Also you first need to put in place a way to override how to obtain the
> cpumode, then you should use it.
>
> Also this mode doesn't look feasible at all, think about processing
> perf.data files generated in !powerpc systems being analysed in a
> powerpc system. This has to be dependend on the architecture of the
> machine where the perf.data file was recorded, not on the archictecture
> of the machine the binary was built for.

Valid point.

I'll re-think about approach in this case.

> It is only when you do live analysis, like with 'perf trace' and 'perf
> top' that its guaranteed to be all on the same machine.
>
> IIRC in one of the patches in this series you introduce and use a
> library function on the same patch, please break it into two patches as
> well, lemme see what is the name...
>
> Yeah, it is also in this patch:
>
> perf_evlist__arch_add_default(struct perf_evlist *evlist)
>
> Please add this in a separate patch, stating in the changeset comment
> why it is needed and how architectures can override it.

Will do that. Thanks for reviewing.

Regards,
Ravi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample
  2016-02-01 20:53   ` Arnaldo Carvalho de Melo
@ 2016-02-02  9:07     ` Ravi Bangoria
  0 siblings, 0 replies; 9+ messages in thread
From: Ravi Bangoria @ 2016-02-02  9:07 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: mingo, peterz, linux-kernel, hemant, naveen.n.rao

HI acme,

Thanks for reviewing the patch.

On Tuesday 02 February 2016 02:23 AM, Arnaldo Carvalho de Melo wrote:
> Em Fri, Jan 22, 2016 at 11:28:10AM +0530, Ravi Bangoria escreveu:
>> This patch changes prototype of perf_event__preprocess_sample() with
>> additional argument evsel added at last.
>>
>> This change is required because perf_event__preprocess_sample()
>> function will use evsel to determine cpumode of samples for powerpc
>> architecture.
>>
>> Signed-off-by: Ravi Bangoria<ravi.bangoria@linux.vnet.ibm.com>
> Fixing these problems:
>
>
>
>    CC       /tmp/build/perf/ui/gtk/util.o
> util/event.c: In function ‘perf_event__preprocess_sample’:
> util/event.c:1302:26: error: unused parameter ‘evsel’ [-Werror=unused-parameter]
>         struct perf_evsel *evsel)
>                            ^
> cc1: all warnings being treated as errors
> mv: cannot stat ‘/tmp/build/perf/util/.event.o.tmp’: No such file or directory
> /home/acme/git/linux/tools/build/Makefile.build:77: recipe for target '/tmp/build/perf/util/event.o' failed
> make[3]: *** [/tmp/build/perf/util/event.o] Error 1
> make[3]: *** Waiting for unfinished jobs....
>    CC       /tmp/build/perf/ui/gtk/helpline.o
>    CC       /tmp/build/perf/arch/common.o
> /home/acme/git/linux/tools/build/Makefile.build:116: recipe for target 'util' failed
> make[2]: *** [util] Error 2
> make[2]: *** Waiting for unfinished jobs....

Thanks for pointing this out. Actually I was not aware about this.

Will take care next time onwards.

Regards,
Ravi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc
  2016-02-02  9:06     ` Ravi Bangoria
@ 2016-02-09 10:47       ` Ravi Bangoria
  0 siblings, 0 replies; 9+ messages in thread
From: Ravi Bangoria @ 2016-02-09 10:47 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: mingo, peterz, linux-kernel, hemant, Naveen N. Rao, mpe, paulus

Hi acme,

On Tuesday 02 February 2016 02:36 PM, Ravi Bangoria wrote:
> HI acme,
>
> On Tuesday 02 February 2016 02:36 AM, Arnaldo Carvalho de Melo wrote:
>> Em Fri, Jan 22, 2016 at 11:28:11AM +0530, Ravi Bangoria escreveu:
>>> +    return event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
>>> +}
>> This hunk and the next should be on the previous patch, that is not even
>> compiling...
>>
>> You have to compile patch by patch, we can't just test at the end of a
>> patchkit like this, this destroys bisection ;-\
>
> Didn't aware about that. Will take care of compiling each patch
> separately next time onwards.
>
>> Also you first need to put in place a way to override how to obtain the
>> cpumode, then you should use it.
>>
>> Also this mode doesn't look feasible at all, think about processing
>> perf.data files generated in !powerpc systems being analysed in a
>> powerpc system. This has to be dependend on the architecture of the
>> machine where the perf.data file was recorded, not on the archictecture
>> of the machine the binary was built for.
>
> Valid point.
>
> I'll re-think about approach in this case.
>

I've analyzed the approach. Here is my observations:

1. With the current approach, record on !powerpc and report on powerpc
will work as we are solely dependent on tracepoint; so we don't change ip
and cpumode of sample if it's not of kvm_hv:kvm_guest_exit.

2. However, record on powerpc and report on !powerpc won't work with the
current approach. To enable that, we have two options:

Option A. Change ip and cpumode of sample at a time of record.
This will add overhead at a time of recording data and it may have
bad effect like data lost.

Option B. Extension to current approach (change ip and cpumode at
report time only).
I'll need to move 'most of' the code from arch/powerpc/util/kvm.c into
some common code which is included on all architectures. And use
this code to make decision about changing ip and cpumode of sample
at run time. So these functions needs to be present in a binary,
no matter which platform it's compiled on.

I want your suggestions here, how best we can achieve that?

Regards,
Ravi

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-02-09 10:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-22  5:58 [PATCH v2 0/3] perf kvm: Guest Symbol Resolution for powerpc Ravi Bangoria
2016-01-22  5:58 ` [PATCH v2 1/3] perf kvm: Introduce evsel as argument to perf_event__preprocess_sample Ravi Bangoria
2016-02-01 20:53   ` Arnaldo Carvalho de Melo
2016-02-02  9:07     ` Ravi Bangoria
2016-01-22  5:58 ` [PATCH v2 2/3] perf kvm: enable record|report feature on powerpc Ravi Bangoria
2016-02-01 21:06   ` Arnaldo Carvalho de Melo
2016-02-02  9:06     ` Ravi Bangoria
2016-02-09 10:47       ` Ravi Bangoria
2016-01-22  5:58 ` [PATCH v2 3/3] perf kvm: Fix output fields instead of 'trace' for perf kvm report " Ravi Bangoria

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.