Loading arch/powerpc/include/asm/cell-pmu.h +2 −0 Original line number Diff line number Diff line Loading @@ -37,9 +37,11 @@ #define CBE_PM_STOP_AT_MAX 0x40000000 #define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3) #define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28) #define CBE_PM_TRACE_BUF_OVFLW(bit) (((bit) & 0x1) << 17) #define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18) #define CBE_PM_FREEZE_ALL_CTRS 0x00100000 #define CBE_PM_ENABLE_EXT_TRACE 0x00008000 #define CBE_PM_SPU_ADDR_TRACE_SET(msk) (((msk) & 0x3) << 9) /* Macros for the trace_address register. */ #define CBE_PM_TRACE_BUF_FULL 0x00000800 Loading arch/powerpc/include/asm/oprofile_impl.h +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ struct op_system_config { unsigned long mmcr0; unsigned long mmcr1; unsigned long mmcra; #ifdef CONFIG_OPROFILE_CELL /* Register for oprofile user tool to check cell kernel profiling * suport. */ unsigned long cell_support; #endif #endif unsigned long enable_kernel; unsigned long enable_user; Loading arch/powerpc/oprofile/cell/pr_util.h +8 −3 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -89,10 +93,11 @@ 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); void stop_spu_profiling(void); 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); Loading arch/powerpc/oprofile/cell/spu_profiler.c +43 −13 Original line number Diff line number Diff line Loading @@ -18,11 +18,21 @@ #include <asm/cell-pmu.h> #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; Loading @@ -31,8 +41,8 @@ static unsigned int profiling_interval; #define SPU_PC_MASK 0xFFFF static DEFINE_SPINLOCK(sample_array_lock); unsigned long sample_array_lock_flags; 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) { Loading Loading @@ -145,13 +155,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; } Loading @@ -162,8 +172,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 */ Loading @@ -182,13 +192,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; Loading @@ -212,10 +222,30 @@ int start_spu_profiling(unsigned int cycles_reset) return 0; } void stop_spu_profiling(void) /* * 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; hrtimer_cancel(&timer); kfree(samples); pr_debug("SPU_PROF: stop_spu_profiling issued\n"); pr_debug("SPU_PROF: stop_spu_profiling_cycles issued\n"); } void stop_spu_profiling_events(void) { spu_prof_running = 0; } arch/powerpc/oprofile/common.c +22 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,28 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); #ifdef CONFIG_OPROFILE_CELL /* create a file the user tool can check to see what level of profiling * support exits with this kernel. Initialize bit mask to indicate * what support the kernel has: * bit 0 - Supports SPU event profiling in addition to PPU * event and cycles; and SPU cycle profiling * bits 1-31 - Currently unused. * * If the file does not exist, then the kernel only supports SPU * cycle profiling, PPU event and cycle profiling. */ oprofilefs_create_ulong(sb, root, "cell_support", &sys.cell_support); sys.cell_support = 0x1; /* Note, the user OProfile tool must check * that this bit is set before attempting to * user SPU event profiling. Older kernels * will not have this file, hence the user * tool is not allowed to do SPU event * profiling on older kernels. Older kernels * will accept SPU events but collected data * is garbage. */ #endif #endif for (i = 0; i < model->num_counters; ++i) { Loading Loading
arch/powerpc/include/asm/cell-pmu.h +2 −0 Original line number Diff line number Diff line Loading @@ -37,9 +37,11 @@ #define CBE_PM_STOP_AT_MAX 0x40000000 #define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3) #define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28) #define CBE_PM_TRACE_BUF_OVFLW(bit) (((bit) & 0x1) << 17) #define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18) #define CBE_PM_FREEZE_ALL_CTRS 0x00100000 #define CBE_PM_ENABLE_EXT_TRACE 0x00008000 #define CBE_PM_SPU_ADDR_TRACE_SET(msk) (((msk) & 0x3) << 9) /* Macros for the trace_address register. */ #define CBE_PM_TRACE_BUF_FULL 0x00000800 Loading
arch/powerpc/include/asm/oprofile_impl.h +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ struct op_system_config { unsigned long mmcr0; unsigned long mmcr1; unsigned long mmcra; #ifdef CONFIG_OPROFILE_CELL /* Register for oprofile user tool to check cell kernel profiling * suport. */ unsigned long cell_support; #endif #endif unsigned long enable_kernel; unsigned long enable_user; Loading
arch/powerpc/oprofile/cell/pr_util.h +8 −3 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -89,10 +93,11 @@ 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); void stop_spu_profiling(void); 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); Loading
arch/powerpc/oprofile/cell/spu_profiler.c +43 −13 Original line number Diff line number Diff line Loading @@ -18,11 +18,21 @@ #include <asm/cell-pmu.h> #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; Loading @@ -31,8 +41,8 @@ static unsigned int profiling_interval; #define SPU_PC_MASK 0xFFFF static DEFINE_SPINLOCK(sample_array_lock); unsigned long sample_array_lock_flags; 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) { Loading Loading @@ -145,13 +155,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; } Loading @@ -162,8 +172,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 */ Loading @@ -182,13 +192,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; Loading @@ -212,10 +222,30 @@ int start_spu_profiling(unsigned int cycles_reset) return 0; } void stop_spu_profiling(void) /* * 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; hrtimer_cancel(&timer); kfree(samples); pr_debug("SPU_PROF: stop_spu_profiling issued\n"); pr_debug("SPU_PROF: stop_spu_profiling_cycles issued\n"); } void stop_spu_profiling_events(void) { spu_prof_running = 0; }
arch/powerpc/oprofile/common.c +22 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,28 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); #ifdef CONFIG_OPROFILE_CELL /* create a file the user tool can check to see what level of profiling * support exits with this kernel. Initialize bit mask to indicate * what support the kernel has: * bit 0 - Supports SPU event profiling in addition to PPU * event and cycles; and SPU cycle profiling * bits 1-31 - Currently unused. * * If the file does not exist, then the kernel only supports SPU * cycle profiling, PPU event and cycle profiling. */ oprofilefs_create_ulong(sb, root, "cell_support", &sys.cell_support); sys.cell_support = 0x1; /* Note, the user OProfile tool must check * that this bit is set before attempting to * user SPU event profiling. Older kernels * will not have this file, hence the user * tool is not allowed to do SPU event * profiling on older kernels. Older kernels * will accept SPU events but collected data * is garbage. */ #endif #endif for (i = 0; i < model->num_counters; ++i) { Loading