diff options
| author | Robert Richter | 2009-01-08 15:54:04 +0100 | 
|---|---|---|
| committer | Robert Richter | 2009-01-08 15:54:04 +0100 | 
| commit | a076aa4f96f40fc75451ae835a1a665ce1faf951 (patch) | |
| tree | 348be8bb538f9f47da8ec237f7bbad63088af929 /arch/powerpc/oprofile/cell | |
| parent | Merge branch 'oprofile/ring_buffer' into oprofile/oprofile-for-tip (diff) | |
| parent | powerpc/oprofile: fix whitespaces in op_model_cell.c (diff) | |
| download | kernel-qcow2-linux-a076aa4f96f40fc75451ae835a1a665ce1faf951.tar.gz kernel-qcow2-linux-a076aa4f96f40fc75451ae835a1a665ce1faf951.tar.xz kernel-qcow2-linux-a076aa4f96f40fc75451ae835a1a665ce1faf951.zip | |
Merge branch 'oprofile/cell' into oprofile/oprofile-for-tip
Diffstat (limited to 'arch/powerpc/oprofile/cell')
| -rw-r--r-- | arch/powerpc/oprofile/cell/pr_util.h | 11 | ||||
| -rw-r--r-- | arch/powerpc/oprofile/cell/spu_profiler.c | 56 | 
2 files changed, 51 insertions, 16 deletions
| diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h index 628009c01958..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 */ @@ -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); diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index dd499c3e9da7..de170b7ae71b 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -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; @@ -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)  { @@ -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;  		} @@ -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 */ @@ -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; @@ -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;  } | 
