* [PATCH] powerpc: Remove some ifdefs in oprofile_impl.h
@ 2006-03-27 0:23 Anton Blanchard
2006-03-27 0:46 ` [PATCH] powerpc: export validate_sp for oprofile calltrace Anton Blanchard
0 siblings, 1 reply; 5+ messages in thread
From: Anton Blanchard @ 2006-03-27 0:23 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
- No one uses op_counter_config.valid, so remove it
- No need to ifdef around function protypes.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-2.6/include/asm-powerpc/oprofile_impl.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/oprofile_impl.h 2006-03-26 12:17:23.000000000 +1100
+++ linux-2.6/include/asm-powerpc/oprofile_impl.h 2006-03-26 12:21:13.000000000 +1100
@@ -17,9 +17,6 @@
/* Per-counter configuration as set via oprofilefs. */
struct op_counter_config {
-#ifdef __powerpc64__
- unsigned long valid;
-#endif
unsigned long enabled;
unsigned long event;
unsigned long count;
@@ -56,17 +53,12 @@ struct op_powerpc_model {
int num_counters;
};
-#ifdef CONFIG_FSL_BOOKE
extern struct op_powerpc_model op_model_fsl_booke;
-#else /* Otherwise, it's classic */
-
-#ifdef CONFIG_PPC64
extern struct op_powerpc_model op_model_rs64;
extern struct op_powerpc_model op_model_power4;
-
-#else /* Otherwise, CONFIG_PPC32 */
extern struct op_powerpc_model op_model_7450;
-#endif
+
+#ifndef CONFIG_FSL_BOOKE
/* All the classic PPC parts use these */
static inline unsigned int ctr_read(unsigned int i)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] powerpc: export validate_sp for oprofile calltrace
2006-03-27 0:23 [PATCH] powerpc: Remove some ifdefs in oprofile_impl.h Anton Blanchard
@ 2006-03-27 0:46 ` Anton Blanchard
2006-03-27 0:57 ` [PATCH] powerpc: Add oprofile calltrace support Anton Blanchard
0 siblings, 1 reply; 5+ messages in thread
From: Anton Blanchard @ 2006-03-27 0:46 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
Export validate_sp so we can use it in the oprofile calltrace code.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: build/arch/powerpc/kernel/process.c
===================================================================
--- build.orig/arch/powerpc/kernel/process.c 2006-03-26 10:39:29.000000000 +1000
+++ build/arch/powerpc/kernel/process.c 2006-03-26 12:48:03.000000000 +1000
@@ -767,7 +767,7 @@ out:
return error;
}
-static int validate_sp(unsigned long sp, struct task_struct *p,
+int validate_sp(unsigned long sp, struct task_struct *p,
unsigned long nbytes)
{
unsigned long stack_page = (unsigned long)task_stack_page(p);
@@ -805,6 +805,8 @@ static int validate_sp(unsigned long sp,
#define FRAME_MARKER 2
#endif
+EXPORT_SYMBOL(validate_sp);
+
unsigned long get_wchan(struct task_struct *p)
{
unsigned long ip, sp;
Index: build/include/asm-powerpc/processor.h
===================================================================
--- build.orig/include/asm-powerpc/processor.h 2006-03-24 15:51:22.000000000 +1100
+++ build/include/asm-powerpc/processor.h 2006-03-26 12:48:03.000000000 +1000
@@ -251,6 +251,10 @@ static inline unsigned long __pack_fe01(
#define cpu_relax() barrier()
#endif
+/* Check that a certain kernel stack pointer is valid in task_struct p */
+int validate_sp(unsigned long sp, struct task_struct *p,
+ unsigned long nbytes);
+
/*
* Prefetch macros.
*/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] powerpc: Add oprofile calltrace support
2006-03-27 0:46 ` [PATCH] powerpc: export validate_sp for oprofile calltrace Anton Blanchard
@ 2006-03-27 0:57 ` Anton Blanchard
2006-03-27 1:00 ` [PATCH] powerpc: Remove oprofile spinlock backtrace code Anton Blanchard
0 siblings, 1 reply; 5+ messages in thread
From: Anton Blanchard @ 2006-03-27 0:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: bcr6, paulus
From: Brian Rogan <bcr6@cornell.edu>
Add oprofile calltrace support to powerpc. Disable spinlock backtracing
now we can use calltrace info.
(Updated to work on both 32bit and 64bit by me).
Signed-off-by: Anton Blanchard <anton@samba.org>
---
This patch depends on a patch currently in -mm:
http://marc.theaimsgroup.com/?l=linux-kernel&m=114333745914386&w=2
Index: build/arch/powerpc/oprofile/backtrace.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ build/arch/powerpc/oprofile/backtrace.c 2006-03-26 15:13:57.000000000 +1000
@@ -0,0 +1,126 @@
+/**
+ * Copyright (C) 2005 Brian Rogan <bcr6@cornell.edu>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+**/
+
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+#define STACK_SP(STACK) *(STACK)
+
+#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2)
+#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1)
+
+#ifdef CONFIG_PPC64
+#define STACK_LR(STACK) STACK_LR64(STACK)
+#else
+#define STACK_LR(STACK) STACK_LR32(STACK)
+#endif
+
+static unsigned int user_getsp32(unsigned int sp, int is_first)
+{
+ unsigned int stack_frame[2];
+
+ if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ return 0;
+
+ /*
+ * The most likely reason for this is that we returned -EFAULT,
+ * which means that we've done all that we can do from
+ * interrupt context.
+ */
+ if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
+ sizeof(stack_frame)))
+ return 0;
+
+ if (!is_first)
+ oprofile_add_trace(STACK_LR32(stack_frame));
+
+ /*
+ * We do not enforce increasing stack addresses here because
+ * we may transition to a different stack, eg a signal handler.
+ */
+ return STACK_SP(stack_frame);
+}
+
+#ifdef CONFIG_PPC64
+static unsigned long user_getsp64(unsigned long sp, int is_first)
+{
+ unsigned long stack_frame[3];
+
+ if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ return 0;
+
+ if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+ sizeof(stack_frame)))
+ return 0;
+
+ if (!is_first)
+ oprofile_add_trace(STACK_LR64(stack_frame));
+
+ return STACK_SP(stack_frame);
+}
+#endif
+
+static unsigned long kernel_getsp(unsigned long sp, int is_first)
+{
+ unsigned long *stack_frame = (unsigned long *)sp;
+
+ if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
+ return 0;
+
+ if (!is_first)
+ oprofile_add_trace(STACK_LR(stack_frame));
+
+ /*
+ * We do not enforce increasing stack addresses here because
+ * we might be transitioning from an interrupt stack to a kernel
+ * stack. validate_sp() is designed to understand this, so just
+ * use it.
+ */
+ return STACK_SP(stack_frame);
+}
+
+void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+ unsigned long sp = regs->gpr[1];
+ int first_frame = 1;
+
+ /* We ditch the top stackframe so need to loop through an extra time */
+ depth += 1;
+
+ if (!user_mode(regs)) {
+ while (depth--) {
+ sp = kernel_getsp(sp, first_frame);
+ if (!sp)
+ break;
+ first_frame = 0;
+ }
+ } else {
+#ifdef CONFIG_PPC64
+ if (!test_thread_flag(TIF_32BIT)) {
+ while (depth--) {
+ sp = user_getsp64(sp, first_frame);
+ if (!sp)
+ break;
+ first_frame = 0;
+ }
+
+ return;
+ }
+#endif
+
+ while (depth--) {
+ sp = user_getsp32(sp, first_frame);
+ if (!sp)
+ break;
+ first_frame = 0;
+ }
+ }
+}
Index: build/arch/powerpc/oprofile/common.c
===================================================================
--- build.orig/arch/powerpc/oprofile/common.c 2006-01-16 00:05:48.000000000 +1100
+++ build/arch/powerpc/oprofile/common.c 2006-03-26 13:09:34.000000000 +1000
@@ -126,8 +126,7 @@ static int op_powerpc_create_files(struc
sys.enable_kernel = 1;
sys.enable_user = 1;
#ifdef CONFIG_PPC64
- /* Turn on backtracing through spinlocks by default */
- sys.backtrace_spinlocks = 1;
+ sys.backtrace_spinlocks = 0;
#endif
return 0;
@@ -168,6 +167,7 @@ int __init oprofile_arch_init(struct opr
ops->shutdown = op_powerpc_shutdown;
ops->start = op_powerpc_start;
ops->stop = op_powerpc_stop;
+ ops->backtrace = op_powerpc_backtrace;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
ops->cpu_type);
Index: build/arch/powerpc/oprofile/Makefile
===================================================================
--- build.orig/arch/powerpc/oprofile/Makefile 2006-03-26 10:40:14.000000000 +1000
+++ build/arch/powerpc/oprofile/Makefile 2006-03-26 13:09:34.000000000 +1000
@@ -10,7 +10,7 @@ DRIVER_OBJS := $(addprefix ../../../driv
oprofilefs.o oprofile_stats.o \
timer_int.o )
-oprofile-y := $(DRIVER_OBJS) common.o
+oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
oprofile-$(CONFIG_PPC32) += op_model_7450.o
Index: build/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- build.orig/arch/powerpc/oprofile/op_model_power4.c 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/oprofile/op_model_power4.c 2006-03-26 13:09:34.000000000 +1000
@@ -293,7 +293,7 @@ static void power4_handle_interrupt(stru
val = ctr_read(i);
if (val < 0) {
if (oprofile_running && ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel, i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
ctr_write(i, reset_value[i]);
} else {
ctr_write(i, 0);
Index: build/include/asm-powerpc/oprofile_impl.h
===================================================================
--- build.orig/include/asm-powerpc/oprofile_impl.h 2006-03-26 12:48:01.000000000 +1000
+++ build/include/asm-powerpc/oprofile_impl.h 2006-03-26 13:09:34.000000000 +1000
@@ -126,5 +126,7 @@ static inline void ctr_write(unsigned in
}
#endif /* !CONFIG_FSL_BOOKE */
+extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] powerpc: Remove oprofile spinlock backtrace code
2006-03-27 0:57 ` [PATCH] powerpc: Add oprofile calltrace support Anton Blanchard
@ 2006-03-27 1:00 ` Anton Blanchard
2006-03-27 1:03 ` [PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus Anton Blanchard
0 siblings, 1 reply; 5+ messages in thread
From: Anton Blanchard @ 2006-03-27 1:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
Remove oprofile spinlock backtrace code now we have proper calltrace
support. Also make MMCRA sihv and sipr bits a variable since they may
change in future cpus. Finally, MMCRA should be a 64bit quantity.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-2.6/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_power4.c 2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_power4.c 2006-03-26 17:55:19.000000000 +1100
@@ -25,18 +25,14 @@ static unsigned long reset_value[OP_MAX_
static int oprofile_running;
static int mmcra_has_sihv;
+/* Unfortunately these bits vary between CPUs */
+static unsigned long mmcra_sihv = MMCRA_SIHV;
+static unsigned long mmcra_sipr = MMCRA_SIPR;
/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
static u32 mmcr0_val;
static u64 mmcr1_val;
-static u32 mmcra_val;
-
-/*
- * Since we do not have an NMI, backtracing through spinlocks is
- * only a best guess. In light of this, allow it to be disabled at
- * runtime.
- */
-static int backtrace_spinlocks;
+static u64 mmcra_val;
static void power4_reg_setup(struct op_counter_config *ctr,
struct op_system_config *sys,
@@ -63,8 +59,6 @@ static void power4_reg_setup(struct op_c
mmcr1_val = sys->mmcr1;
mmcra_val = sys->mmcra;
- backtrace_spinlocks = sys->backtrace_spinlocks;
-
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count;
@@ -197,25 +191,6 @@ static void __attribute_used__ kernel_un
{
}
-static unsigned long check_spinlock_pc(struct pt_regs *regs,
- unsigned long profile_pc)
-{
- unsigned long pc = instruction_pointer(regs);
-
- /*
- * If both the SIAR (sampled instruction) and the perfmon exception
- * occurred in a spinlock region then we account the sample to the
- * calling function. This isnt 100% correct, we really need soft
- * IRQ disable so we always get the perfmon exception at the
- * point at which the SIAR is set.
- */
- if (backtrace_spinlocks && in_lock_functions(pc) &&
- in_lock_functions(profile_pc))
- return regs->link;
- else
- return profile_pc;
-}
-
/*
* On GQ and newer the MMCRA stores the HV and PR bits at the time
* the SIAR was sampled. We use that to work out if the SIAR was sampled in
@@ -228,17 +203,17 @@ static unsigned long get_pc(struct pt_re
/* Cant do much about it */
if (!mmcra_has_sihv)
- return check_spinlock_pc(regs, pc);
+ return pc;
mmcra = mfspr(SPRN_MMCRA);
/* Were we in the hypervisor? */
- if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV))
+ if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv))
/* function descriptor madness */
return *((unsigned long *)hypervisor_bucket);
/* We were in userspace, nothing to do */
- if (mmcra & MMCRA_SIPR)
+ if (mmcra & mmcra_sipr)
return pc;
#ifdef CONFIG_PPC_RTAS
@@ -257,7 +232,7 @@ static unsigned long get_pc(struct pt_re
/* function descriptor madness */
return *((unsigned long *)kernel_unknown_bucket);
- return check_spinlock_pc(regs, pc);
+ return pc;
}
static int get_kernel(unsigned long pc)
@@ -268,7 +243,7 @@ static int get_kernel(unsigned long pc)
is_kernel = is_kernel_addr(pc);
} else {
unsigned long mmcra = mfspr(SPRN_MMCRA);
- is_kernel = ((mmcra & MMCRA_SIPR) == 0);
+ is_kernel = ((mmcra & mmcra_sipr) == 0);
}
return is_kernel;
Index: linux-2.6/arch/powerpc/oprofile/common.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/common.c 2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/common.c 2006-03-26 17:55:19.000000000 +1100
@@ -117,17 +117,10 @@ static int op_powerpc_create_files(struc
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-#ifdef CONFIG_PPC64
- oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
- &sys.backtrace_spinlocks);
-#endif
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
-#ifdef CONFIG_PPC64
- sys.backtrace_spinlocks = 0;
-#endif
return 0;
}
Index: linux-2.6/include/asm-powerpc/oprofile_impl.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/oprofile_impl.h 2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/include/asm-powerpc/oprofile_impl.h 2006-03-26 17:55:19.000000000 +1100
@@ -35,9 +35,6 @@ struct op_system_config {
#endif
unsigned long enable_kernel;
unsigned long enable_user;
-#ifdef CONFIG_PPC64
- unsigned long backtrace_spinlocks;
-#endif
};
/* Per-arch configuration */
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus
2006-03-27 1:00 ` [PATCH] powerpc: Remove oprofile spinlock backtrace code Anton Blanchard
@ 2006-03-27 1:03 ` Anton Blanchard
0 siblings, 0 replies; 5+ messages in thread
From: Anton Blanchard @ 2006-03-27 1:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
Add calltrace support for other powerpc cpus. Tested on 7450.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-2.6/arch/powerpc/oprofile/op_model_7450.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_7450.c 2006-01-19 12:29:53.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_7450.c 2006-03-26 23:00:02.000000000 +1100
@@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(str
mtmsr(mfmsr() | MSR_PMM);
pc = mfspr(SPRN_SIAR);
- is_kernel = (pc >= KERNELBASE);
+ is_kernel = is_kernel_addr(pc);
for (i = 0; i < NUM_CTRS; ++i) {
val = ctr_read(i);
if (val < 0) {
if (oprofile_running && ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel, i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
ctr_write(i, reset_value[i]);
} else {
ctr_write(i, 0);
Index: linux-2.6/arch/powerpc/oprofile/op_model_fsl_booke.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_fsl_booke.c 2005-11-16 03:21:49.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_fsl_booke.c 2006-03-26 22:58:08.000000000 +1100
@@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(s
mtmsr(mfmsr() | MSR_PMM);
pc = regs->nip;
- is_kernel = (pc >= KERNELBASE);
+ is_kernel = is_kernel_addr(pc);
for (i = 0; i < num_counters; ++i) {
val = ctr_read(i);
if (val < 0) {
if (oprofile_running && ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel, i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
ctr_write(i, reset_value[i]);
} else {
ctr_write(i, 0);
Index: linux-2.6/arch/powerpc/oprofile/op_model_rs64.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_rs64.c 2006-01-19 12:29:53.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_rs64.c 2006-03-26 23:01:55.000000000 +1100
@@ -175,10 +175,13 @@ static void rs64_handle_interrupt(struct
struct op_counter_config *ctr)
{
unsigned int mmcr0;
+ int is_kernel;
int val;
int i;
unsigned long pc = mfspr(SPRN_SIAR);
+ is_kernel = is_kernel_addr(pc);
+
/* set the PMM bit (see comment below) */
mtmsrd(mfmsr() | MSR_PMM);
@@ -186,7 +189,7 @@ static void rs64_handle_interrupt(struct
val = ctr_read(i);
if (val < 0) {
if (ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel_addr(pc), i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
ctr_write(i, reset_value[i]);
} else {
ctr_write(i, 0);
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-03-27 1:03 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-27 0:23 [PATCH] powerpc: Remove some ifdefs in oprofile_impl.h Anton Blanchard
2006-03-27 0:46 ` [PATCH] powerpc: export validate_sp for oprofile calltrace Anton Blanchard
2006-03-27 0:57 ` [PATCH] powerpc: Add oprofile calltrace support Anton Blanchard
2006-03-27 1:00 ` [PATCH] powerpc: Remove oprofile spinlock backtrace code Anton Blanchard
2006-03-27 1:03 ` [PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus Anton Blanchard
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).