Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ce5f241 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile: (31 commits)
  powerpc/oprofile: fix whitespaces in op_model_cell.c
  powerpc/oprofile: IBM CELL: add SPU event profiling support
  powerpc/oprofile: fix cell/pr_util.h
  powerpc/oprofile: IBM CELL: cleanup and restructuring
  oprofile: make new cpu buffer functions part of the api
  oprofile: remove #ifdef CONFIG_OPROFILE_IBS in non-ibs code
  ring_buffer: fix ring_buffer_event_length()
  oprofile: use new data sample format for ibs
  oprofile: add op_cpu_buffer_get_data()
  oprofile: add op_cpu_buffer_add_data()
  oprofile: rework implementation of cpu buffer events
  oprofile: modify op_cpu_buffer_read_entry()
  oprofile: add op_cpu_buffer_write_reserve()
  oprofile: rename variables in add_ibs_begin()
  oprofile: rename add_sample() in cpu_buffer.c
  oprofile: rename variable ibs_allowed to has_ibs in op_model_amd.c
  oprofile: making add_sample_entry() inline
  oprofile: remove backtrace code for ibs
  oprofile: remove unused ibs macro
  oprofile: remove unused components in struct oprofile_cpu_buffer
  ...
parents 7c51d57e a076aa4f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -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;
+8 −3
Original line number Diff line number Diff line
@@ -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);
+43 −13
Original line number Diff line number Diff line
@@ -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;
}
+22 −0
Original line number Diff line number Diff line
@@ -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