From 9b93418e7ee59dbc96d44cfde7f65f886e54dba9 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Mon, 1 Dec 2008 16:18:34 -0800 Subject: powerpc/oprofile: IBM CELL: cleanup and restructuring This patch restructures and cleans up the code a bit to make it easier to add new functionality later. The patch makes no functional changes to the existing code. Signed-off-by: Carl Love Signed-off-by: Robert Richter --- arch/powerpc/oprofile/cell/spu_profiler.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/powerpc/oprofile/cell') diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index dd499c3e9da7..8b1b9ccaff9f 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -31,8 +31,8 @@ static unsigned int profiling_interval; #define SPU_PC_MASK 0xFFFF -static DEFINE_SPINLOCK(sample_array_lock); -unsigned long sample_array_lock_flags; +static DEFINE_SPINLOCK(oprof_spu_smpl_arry_lck); +unsigned long oprof_spu_smpl_arry_lck_flags; void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset) { @@ -145,13 +145,13 @@ static enum hrtimer_restart profile_spus(struct hrtimer *timer) * sample array must be loaded and then processed for a given * cpu. The sample array is not per cpu. */ - spin_lock_irqsave(&sample_array_lock, - sample_array_lock_flags); + spin_lock_irqsave(&oprof_spu_smpl_arry_lck, + oprof_spu_smpl_arry_lck_flags); num_samples = cell_spu_pc_collection(cpu); if (num_samples == 0) { - spin_unlock_irqrestore(&sample_array_lock, - sample_array_lock_flags); + spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, + oprof_spu_smpl_arry_lck_flags); continue; } @@ -162,8 +162,8 @@ static enum hrtimer_restart profile_spus(struct hrtimer *timer) num_samples); } - spin_unlock_irqrestore(&sample_array_lock, - sample_array_lock_flags); + spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, + oprof_spu_smpl_arry_lck_flags); } smp_wmb(); /* insure spu event buffer updates are written */ @@ -182,13 +182,13 @@ static enum hrtimer_restart profile_spus(struct hrtimer *timer) static struct hrtimer timer; /* - * Entry point for SPU profiling. + * Entry point for SPU cycle profiling. * NOTE: SPU profiling is done system-wide, not per-CPU. * * cycles_reset is the count value specified by the user when * setting up OProfile to count SPU_CYCLES. */ -int start_spu_profiling(unsigned int cycles_reset) +int start_spu_profiling_cycles(unsigned int cycles_reset) { ktime_t kt; @@ -212,10 +212,10 @@ int start_spu_profiling(unsigned int cycles_reset) return 0; } -void stop_spu_profiling(void) +void stop_spu_profiling_cycles(void) { spu_prof_running = 0; hrtimer_cancel(&timer); kfree(samples); - pr_debug("SPU_PROF: stop_spu_profiling issued\n"); + pr_debug("SPU_PROF: stop_spu_profiling_cycles issued\n"); } -- cgit v1.2.3 From 014cef91ecef9d5e85f9c98a2efbf8a8c4710510 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 8 Jan 2009 15:29:47 +0100 Subject: powerpc/oprofile: fix cell/pr_util.h Signed-off-by: Robert Richter --- arch/powerpc/oprofile/cell/pr_util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/oprofile/cell') diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h index 628009c01958..bca7207bd92a 100644 --- a/arch/powerpc/oprofile/cell/pr_util.h +++ b/arch/powerpc/oprofile/cell/pr_util.h @@ -89,9 +89,9 @@ void vma_map_free(struct vma_to_fileoffset_map *map); * Entry point for SPU profiling. * cycles_reset is the SPU_CYCLES count value specified by the user. */ -int start_spu_profiling(unsigned int cycles_reset); +int start_spu_profiling_cycles(unsigned int cycles_reset); -void stop_spu_profiling(void); +void stop_spu_profiling_cycles(void); /* add the necessary profiling hooks */ -- cgit v1.2.3 From 883823291d22e06736f1056da6d8303291d6bbf9 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Mon, 1 Dec 2008 16:18:36 -0800 Subject: powerpc/oprofile: IBM CELL: add SPU event profiling support This patch adds the SPU event based profiling funcitonality for the IBM Cell processor. Previously, the CELL OProfile kernel code supported PPU event, PPU cycle profiling and SPU cycle profiling. The addition of SPU event profiling allows the users to identify where in their SPU code various SPU evnets are occuring. This should help users further identify issues with their code. Note, SPU profiling has some limitations due to HW constraints. Only one event at a time can be used for profiling and SPU event profiling must be time sliced across all of the SPUs in a node. The patch adds a new arch specific file to the OProfile file system. The file has bit 0 set to indicate that the kernel supports SPU event profiling. The user tool must check this file/bit to make sure the kernel supports SPU event profiling before trying to do SPU event profiling. The user tool check is part of the user tool patch for SPU event profiling. Signed-off-by: Carl Love Signed-off-by: Robert Richter --- arch/powerpc/oprofile/cell/pr_util.h | 7 ++++++- arch/powerpc/oprofile/cell/spu_profiler.c | 34 +++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/oprofile/cell') diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h index bca7207bd92a..a048b0b72be3 100644 --- a/arch/powerpc/oprofile/cell/pr_util.h +++ b/arch/powerpc/oprofile/cell/pr_util.h @@ -30,6 +30,10 @@ extern struct delayed_work spu_work; extern int spu_prof_running; +#define TRACE_ARRAY_SIZE 1024 + +extern spinlock_t oprof_spu_smpl_arry_lck; + struct spu_overlay_info { /* map of sections within an SPU overlay */ unsigned int vma; /* SPU virtual memory address from elf */ unsigned int size; /* size of section from elf */ @@ -90,9 +94,10 @@ void vma_map_free(struct vma_to_fileoffset_map *map); * cycles_reset is the SPU_CYCLES count value specified by the user. */ int start_spu_profiling_cycles(unsigned int cycles_reset); +void start_spu_profiling_events(void); void stop_spu_profiling_cycles(void); - +void stop_spu_profiling_events(void); /* add the necessary profiling hooks */ int spu_sync_start(void); diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index 8b1b9ccaff9f..de170b7ae71b 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -18,11 +18,21 @@ #include #include "pr_util.h" -#define TRACE_ARRAY_SIZE 1024 #define SCALE_SHIFT 14 static u32 *samples; +/* spu_prof_running is a flag used to indicate if spu profiling is enabled + * or not. It is set by the routines start_spu_profiling_cycles() and + * start_spu_profiling_events(). The flag is cleared by the routines + * stop_spu_profiling_cycles() and stop_spu_profiling_events(). These + * routines are called via global_start() and global_stop() which are called in + * op_powerpc_start() and op_powerpc_stop(). These routines are called once + * per system as a result of the user starting/stopping oprofile. Hence, only + * one CPU per user at a time will be changing the value of spu_prof_running. + * In general, OProfile does not protect against multiple users trying to run + * OProfile at a time. + */ int spu_prof_running; static unsigned int profiling_interval; @@ -31,7 +41,7 @@ static unsigned int profiling_interval; #define SPU_PC_MASK 0xFFFF -static DEFINE_SPINLOCK(oprof_spu_smpl_arry_lck); +DEFINE_SPINLOCK(oprof_spu_smpl_arry_lck); unsigned long oprof_spu_smpl_arry_lck_flags; void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset) @@ -212,6 +222,21 @@ int start_spu_profiling_cycles(unsigned int cycles_reset) return 0; } +/* + * Entry point for SPU event profiling. + * NOTE: SPU profiling is done system-wide, not per-CPU. + * + * cycles_reset is the count value specified by the user when + * setting up OProfile to count SPU_CYCLES. + */ +void start_spu_profiling_events(void) +{ + spu_prof_running = 1; + schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); + + return; +} + void stop_spu_profiling_cycles(void) { spu_prof_running = 0; @@ -219,3 +244,8 @@ void stop_spu_profiling_cycles(void) kfree(samples); pr_debug("SPU_PROF: stop_spu_profiling_cycles issued\n"); } + +void stop_spu_profiling_events(void) +{ + spu_prof_running = 0; +} -- cgit v1.2.3