All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers
@ 2012-06-26 11:00 Anton Blanchard
  2012-06-26 11:01 ` [PATCH 2/4] powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs Anton Blanchard
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Anton Blanchard @ 2012-06-26 11:00 UTC (permalink / raw)
  To: benh, paulus, sukadev; +Cc: linuxppc-dev


We want to access the MMCRA_SIHV and MMCRA_SIPR bits elsewhere so 
create mmcra_sihv and mmcra_sipr which hide the differences between
the old and new layout of the bits.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-build/arch/powerpc/perf/core-book3s.c
===================================================================
--- linux-build.orig/arch/powerpc/perf/core-book3s.c	2012-06-26 10:26:40.695707845 +1000
+++ linux-build/arch/powerpc/perf/core-book3s.c	2012-06-26 10:28:53.325958826 +1000
@@ -116,6 +116,26 @@ static inline void perf_get_data_addr(st
 		*addrp = mfspr(SPRN_SDAR);
 }
 
+static bool mmcra_sihv(unsigned long mmcra)
+{
+	unsigned long sihv = MMCRA_SIHV;
+
+	if (ppmu->flags & PPMU_ALT_SIPR)
+		sihv = POWER6_MMCRA_SIHV;
+
+	return !!(mmcra & sihv);
+}
+
+static bool mmcra_sipr(unsigned long mmcra)
+{
+	unsigned long sipr = MMCRA_SIPR;
+
+	if (ppmu->flags & PPMU_ALT_SIPR)
+		sipr = POWER6_MMCRA_SIPR;
+
+	return !!(mmcra & sipr);
+}
+
 static inline u32 perf_flags_from_msr(struct pt_regs *regs)
 {
 	if (regs->msr & MSR_PR)
@@ -128,8 +148,6 @@ static inline u32 perf_flags_from_msr(st
 static inline u32 perf_get_misc_flags(struct pt_regs *regs)
 {
 	unsigned long mmcra = regs->dsisr;
-	unsigned long sihv = MMCRA_SIHV;
-	unsigned long sipr = MMCRA_SIPR;
 
 	/* Not a PMU interrupt: Make up flags from regs->msr */
 	if (TRAP(regs) != 0xf00)
@@ -156,15 +174,10 @@ static inline u32 perf_get_misc_flags(st
 		return PERF_RECORD_MISC_USER;
 	}
 
-	if (ppmu->flags & PPMU_ALT_SIPR) {
-		sihv = POWER6_MMCRA_SIHV;
-		sipr = POWER6_MMCRA_SIPR;
-	}
-
 	/* PR has priority over HV, so order below is important */
-	if (mmcra & sipr)
+	if (mmcra_sipr(mmcra))
 		return PERF_RECORD_MISC_USER;
-	if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV))
+	if (mmcra_sihv(mmcra) && (freeze_events_kernel != MMCR0_FCHV))
 		return PERF_RECORD_MISC_HYPERVISOR;
 	return PERF_RECORD_MISC_KERNEL;
 }

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

* [PATCH 2/4] powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs
  2012-06-26 11:00 [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anton Blanchard
@ 2012-06-26 11:01 ` Anton Blanchard
  2012-06-26 11:02 ` [PATCH 3/4] powerpc/perf: Always use pt_regs for userspace samples Anton Blanchard
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Anton Blanchard @ 2012-06-26 11:01 UTC (permalink / raw)
  To: benh, paulus, sukadev; +Cc: linuxppc-dev


The logic to choose whether to use the SIAR or get the information
out of pt_regs is going to get more complicated, so do it once in
perf_read_regs.

We overload regs->result which is gross but we are already doing it
with regs->dsisr.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Other architectures appear to be playing similar overloading tricks
so we should probably solve this in a nicer way.

Index: linux-build/arch/powerpc/include/asm/perf_event.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/perf_event.h	2012-06-26 10:26:40.000000000 +1000
+++ linux-build/arch/powerpc/include/asm/perf_event.h	2012-06-26 10:31:02.132149613 +1000
@@ -26,8 +26,13 @@
 #include <asm/ptrace.h>
 #include <asm/reg.h>
 
+/*
+ * Overload regs->result to specify whether we should use the MSR (result
+ * is zero) or the SIAR (result is non zero).
+ */
 #define perf_arch_fetch_caller_regs(regs, __ip)			\
 	do {							\
+		(regs)->result = 0;				\
 		(regs)->nip = __ip;				\
 		(regs)->gpr[1] = *(unsigned long *)__get_SP();	\
 		asm volatile("mfmsr %0" : "=r" ((regs)->msr));	\
Index: linux-build/arch/powerpc/perf/core-book3s.c
===================================================================
--- linux-build.orig/arch/powerpc/perf/core-book3s.c	2012-06-26 10:28:53.000000000 +1000
+++ linux-build/arch/powerpc/perf/core-book3s.c	2012-06-26 10:35:40.560886839 +1000
@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(st
 {
 	return 0;
 }
-static inline void perf_read_regs(struct pt_regs *regs) { }
+static inline void perf_read_regs(struct pt_regs *regs)
+{
+	regs->result = 0;
+}
 static inline int perf_intr_is_nmi(struct pt_regs *regs)
 {
 	return 0;
@@ -148,17 +151,9 @@ static inline u32 perf_flags_from_msr(st
 static inline u32 perf_get_misc_flags(struct pt_regs *regs)
 {
 	unsigned long mmcra = regs->dsisr;
+	unsigned long use_siar = regs->result;
 
-	/* Not a PMU interrupt: Make up flags from regs->msr */
-	if (TRAP(regs) != 0xf00)
-		return perf_flags_from_msr(regs);
-
-	/*
-	 * If we don't support continuous sampling and this
-	 * is not a marked event, same deal
-	 */
-	if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
-	    !(mmcra & MMCRA_SAMPLE_ENABLE))
+	if (!use_siar)
 		return perf_flags_from_msr(regs);
 
 	/*
@@ -185,10 +180,24 @@ static inline u32 perf_get_misc_flags(st
 /*
  * Overload regs->dsisr to store MMCRA so we only need to read it once
  * on each interrupt.
+ * Overload regs->result to specify whether we should use the MSR (result
+ * is zero) or the SIAR (result is non zero).
  */
 static inline void perf_read_regs(struct pt_regs *regs)
 {
-	regs->dsisr = mfspr(SPRN_MMCRA);
+	unsigned long mmcra = mfspr(SPRN_MMCRA);
+	int marked = mmcra & MMCRA_SAMPLE_ENABLE;
+	int use_siar;
+
+	if (TRAP(regs) != 0xf00)
+		use_siar = 0;
+	else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked)
+		use_siar = 0;
+	else
+		use_siar = 1;
+
+	regs->dsisr = mmcra;
+	regs->result = use_siar;
 }
 
 /*
@@ -1342,18 +1351,12 @@ unsigned long perf_misc_flags(struct pt_
  */
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	unsigned long mmcra = regs->dsisr;
+	unsigned long use_siar = regs->result;
 
-	/* Not a PMU interrupt */
-	if (TRAP(regs) != 0xf00)
-		return regs->nip;
-
-	/* Processor doesn't support sampling non marked events */
-	if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
-	    !(mmcra & MMCRA_SAMPLE_ENABLE))
+	if (use_siar)
+		return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
+	else
 		return regs->nip;
-
-	return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
 }
 
 static bool pmc_overflow(unsigned long val)

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

* [PATCH 3/4] powerpc/perf: Always use pt_regs for userspace samples
  2012-06-26 11:00 [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anton Blanchard
  2012-06-26 11:01 ` [PATCH 2/4] powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs Anton Blanchard
@ 2012-06-26 11:02 ` Anton Blanchard
  2012-06-26 11:04 ` [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains Anton Blanchard
  2012-07-09  4:20 ` [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anshuman Khandual
  3 siblings, 0 replies; 8+ messages in thread
From: Anton Blanchard @ 2012-06-26 11:02 UTC (permalink / raw)
  To: benh, paulus, sukadev; +Cc: linuxppc-dev


At the moment we always use the SIAR if the PMU supports continuous
sampling. Unfortunately the SIAR and the PMU exception are not
synchronised for non marked events so we can end up with callchains
that dont make sense.

The following patch checks the HV and PR bits for samples coming from
userspace and always uses pt_regs for them. Userspace will never have
interrupts off so there is no real advantage to using the SIAR for
non marked events in userspace.

I had experimented with a patch that did a similar thing for kernel
samples but we lost a significant amount of information. I was
unable to profile any of our early exception code for example.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-build/arch/powerpc/perf/core-book3s.c
===================================================================
--- linux-build.orig/arch/powerpc/perf/core-book3s.c	2012-06-26 10:45:12.402615339 +1000
+++ linux-build/arch/powerpc/perf/core-book3s.c	2012-06-26 10:51:25.465039364 +1000
@@ -189,9 +189,30 @@ static inline void perf_read_regs(struct
 	int marked = mmcra & MMCRA_SAMPLE_ENABLE;
 	int use_siar;
 
+	/*
+	 * If this isn't a PMU exception (eg a software event) the SIAR is
+	 * not valid. Use pt_regs.
+	 *
+	 * If it is a marked event use the SIAR.
+	 *
+	 * If the PMU doesn't update the SIAR for non marked events use
+	 * pt_regs.
+	 *
+	 * If the PMU has HV/PR flags then check to see if they
+	 * place the exception in userspace. If so, use pt_regs. In
+	 * continuous sampling mode the SIAR and the PMU exception are
+	 * not synchronised, so they may be many instructions apart.
+	 * This can result in confusing backtraces. We still want
+	 * hypervisor samples as well as samples in the kernel with
+	 * interrupts off hence the userspace check.
+	 */
 	if (TRAP(regs) != 0xf00)
 		use_siar = 0;
-	else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked)
+	else if (marked)
+		use_siar = 1;
+	else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING))
+		use_siar = 0;
+	else if (!(ppmu->flags & PPMU_NO_SIPR) && mmcra_sipr(mmcra))
 		use_siar = 0;
 	else
 		use_siar = 1;

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

* [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains
  2012-06-26 11:00 [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anton Blanchard
  2012-06-26 11:01 ` [PATCH 2/4] powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs Anton Blanchard
  2012-06-26 11:02 ` [PATCH 3/4] powerpc/perf: Always use pt_regs for userspace samples Anton Blanchard
@ 2012-06-26 11:04 ` Anton Blanchard
  2012-06-26 23:04   ` Scott Wood
  2012-07-09  4:20 ` [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anshuman Khandual
  3 siblings, 1 reply; 8+ messages in thread
From: Anton Blanchard @ 2012-06-26 11:04 UTC (permalink / raw)
  To: benh, paulus, sukadev; +Cc: linuxppc-dev


We use SIAR or regs->nip for the instruction pointer depending on
the PMU configuration, but we always use regs->nip in the callchain.

Use perf_instruction_pointer so the backtrace is consistent.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-build/arch/powerpc/perf/callchain.c
===================================================================
--- linux-build.orig/arch/powerpc/perf/callchain.c	2012-04-12 11:36:26.236223786 +1000
+++ linux-build/arch/powerpc/perf/callchain.c	2012-06-26 12:49:28.944202712 +1000
@@ -57,7 +57,7 @@ perf_callchain_kernel(struct perf_callch
 
 	lr = regs->link;
 	sp = regs->gpr[1];
-	perf_callchain_store(entry, regs->nip);
+	perf_callchain_store(entry, perf_instruction_pointer(regs));
 
 	if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
 		return;
@@ -238,7 +238,7 @@ static void perf_callchain_user_64(struc
 	struct signal_frame_64 __user *sigframe;
 	unsigned long __user *fp, *uregs;
 
-	next_ip = regs->nip;
+	next_ip = perf_instruction_pointer(regs);
 	lr = regs->link;
 	sp = regs->gpr[1];
 	perf_callchain_store(entry, next_ip);
@@ -444,7 +444,7 @@ static void perf_callchain_user_32(struc
 	long level = 0;
 	unsigned int __user *fp, *uregs;
 
-	next_ip = regs->nip;
+	next_ip = perf_instruction_pointer(regs);
 	lr = regs->link;
 	sp = regs->gpr[1];
 	perf_callchain_store(entry, next_ip);

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

* Re: [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains
  2012-06-26 11:04 ` [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains Anton Blanchard
@ 2012-06-26 23:04   ` Scott Wood
  2012-06-27  3:59     ` Anton Blanchard
  0 siblings, 1 reply; 8+ messages in thread
From: Scott Wood @ 2012-06-26 23:04 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: sukadev, paulus, linuxppc-dev

On 06/26/2012 06:04 AM, Anton Blanchard wrote:
> 
> We use SIAR or regs->nip for the instruction pointer depending on
> the PMU configuration, but we always use regs->nip in the callchain.
> 
> Use perf_instruction_pointer so the backtrace is consistent.
> 
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
> 
> Index: linux-build/arch/powerpc/perf/callchain.c
> ===================================================================
> --- linux-build.orig/arch/powerpc/perf/callchain.c	2012-04-12 11:36:26.236223786 +1000
> +++ linux-build/arch/powerpc/perf/callchain.c	2012-06-26 12:49:28.944202712 +1000
> @@ -57,7 +57,7 @@ perf_callchain_kernel(struct perf_callch
>  
>  	lr = regs->link;
>  	sp = regs->gpr[1];
> -	perf_callchain_store(entry, regs->nip);
> +	perf_callchain_store(entry, perf_instruction_pointer(regs));

Won't this break core-fsl-emb, which doesn't define
perf_instruction_pointer()?

-Scott

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

* Re: [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains
  2012-06-26 23:04   ` Scott Wood
@ 2012-06-27  3:59     ` Anton Blanchard
  2012-06-27 15:03       ` Scott Wood
  0 siblings, 1 reply; 8+ messages in thread
From: Anton Blanchard @ 2012-06-27  3:59 UTC (permalink / raw)
  To: Scott Wood; +Cc: sukadev, paulus, linuxppc-dev


Hi Scott,

> Won't this break core-fsl-emb, which doesn't define
> perf_instruction_pointer()?

It links ok for me. You should get the default version:

#ifndef perf_misc_flags
# define perf_misc_flags(regs) \
                (user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL)
# define perf_instruction_pointer(regs) instruction_pointer(regs)
#endif

Anton

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

* Re: [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains
  2012-06-27  3:59     ` Anton Blanchard
@ 2012-06-27 15:03       ` Scott Wood
  0 siblings, 0 replies; 8+ messages in thread
From: Scott Wood @ 2012-06-27 15:03 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: sukadev, paulus, linuxppc-dev

On 06/26/2012 10:59 PM, Anton Blanchard wrote:
> 
> Hi Scott,
> 
>> Won't this break core-fsl-emb, which doesn't define
>> perf_instruction_pointer()?
> 
> It links ok for me. You should get the default version:
> 
> #ifndef perf_misc_flags
> # define perf_misc_flags(regs) \
>                 (user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL)
> # define perf_instruction_pointer(regs) instruction_pointer(regs)
> #endif

OK, sorry -- forgot to grep outside arch/powerpc. :-)

-Scott

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

* Re: [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers
  2012-06-26 11:00 [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anton Blanchard
                   ` (2 preceding siblings ...)
  2012-06-26 11:04 ` [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains Anton Blanchard
@ 2012-07-09  4:20 ` Anshuman Khandual
  3 siblings, 0 replies; 8+ messages in thread
From: Anshuman Khandual @ 2012-07-09  4:20 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: sukadev, paulus, linuxppc-dev

On Tuesday 26 June 2012 04:30 PM, Anton Blanchard wrote:

> 
> We want to access the MMCRA_SIHV and MMCRA_SIPR bits elsewhere so 
> create mmcra_sihv and mmcra_sipr which hide the differences between
> the old and new layout of the bits.
> 


Hey Anton,

Going further in this direction, we can actually create wrapper functions
to capture SIHV and SIPR values whether they are based out of MMCRA register or
not. It would help us decide PERF_RECORD_MISC_USER | PERF_RECORD_MISC_HYPERVISOR
| PERF_RECORD_MISC_KERNEL hiding the register and related bit details.

> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
> 
> Index: linux-build/arch/powerpc/perf/core-book3s.c
> ===================================================================
> --- linux-build.orig/arch/powerpc/perf/core-book3s.c	2012-06-26 10:26:40.695707845 +1000
> +++ linux-build/arch/powerpc/perf/core-book3s.c	2012-06-26 10:28:53.325958826 +1000
> @@ -116,6 +116,26 @@ static inline void perf_get_data_addr(st
>  		*addrp = mfspr(SPRN_SDAR);
>  }
> 
> +static bool mmcra_sihv(unsigned long mmcra)
> +{
> +	unsigned long sihv = MMCRA_SIHV;
> +
> +	if (ppmu->flags & PPMU_ALT_SIPR)
> +		sihv = POWER6_MMCRA_SIHV;
> +
> +	return !!(mmcra & sihv);
> +}
> +
> +static bool mmcra_sipr(unsigned long mmcra)
> +{
> +	unsigned long sipr = MMCRA_SIPR;
> +
> +	if (ppmu->flags & PPMU_ALT_SIPR)
> +		sipr = POWER6_MMCRA_SIPR;
> +
> +	return !!(mmcra & sipr);
> +}

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

end of thread, other threads:[~2012-07-09  4:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-26 11:00 [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anton Blanchard
2012-06-26 11:01 ` [PATCH 2/4] powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs Anton Blanchard
2012-06-26 11:02 ` [PATCH 3/4] powerpc/perf: Always use pt_regs for userspace samples Anton Blanchard
2012-06-26 11:04 ` [PATCH 4/4] powerpc/perf: Use perf_instruction_pointer in callchains Anton Blanchard
2012-06-26 23:04   ` Scott Wood
2012-06-27  3:59     ` Anton Blanchard
2012-06-27 15:03       ` Scott Wood
2012-07-09  4:20 ` [PATCH 1/4] powerpc/perf: Create mmcra_sihv/mmcra_sipv helpers Anshuman Khandual

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.