* [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).