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

Commit 88382329 authored by Carl Love's avatar Carl Love Committed by Robert Richter
Browse files

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: default avatarCarl Love <carll@us.ibm.com>
Signed-off-by: default avatarRobert Richter <robert.richter@amd.com>
parent 014cef91
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;
+6 −1
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 */
@@ -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);
+32 −2
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,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;
}
+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