Skip to content

Commit

Permalink
[POWERPC] spufs: Add marker-based tracing facility
Browse files Browse the repository at this point in the history
This adds markers two important points in the spufs code and a new
module (sputrace.ko) that allows reading these out through a proc file.

Long-term I'd rather see something like lttng extended to use the spufs
instrumentation, but for now I think this is a good enough quick
solution.  We'll probably want to add various addition event in addition
to that ones I have already.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Christoph Hellwig authored and Paul Mackerras committed Feb 6, 2008
1 parent 551e4fb commit 038200c
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 7 deletions.
7 changes: 7 additions & 0 deletions arch/powerpc/platforms/cell/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ config SPU_FS_64K_LS
uses 4K pages. This can improve performances of applications
using multiple SPEs by lowering the TLB pressure on them.

config SPU_TRACE
tristate "SPU event tracing support"
depends on SPU_FS && MARKERS
help
This option allows reading a trace of spu-related events through
the sputrace file in procfs.

config SPU_BASE
bool
default n
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/platforms/cell/spufs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ spufs-y += inode.o file.o context.o syscalls.o coredump.o
spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
spufs-y += switch.o fault.o lscsa_alloc.o

obj-$(CONFIG_SPU_TRACE) += sputrace.o

# Rules to build switch.o with the help of SPU tool chain
SPU_CROSS := spu-
SPU_CC := $(SPU_CROSS)gcc
Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/platforms/cell/spufs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/poll.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
#include <linux/marker.h>

#include <asm/io.h>
#include <asm/semaphore.h>
Expand Down Expand Up @@ -358,6 +359,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
struct spu_context *ctx = vma->vm_file->private_data;
unsigned long area, offset = address - vma->vm_start;

spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);

offset += vma->vm_pgoff << PAGE_SHIFT;
if (offset >= ps_size)
return NOPFN_SIGBUS;
Expand All @@ -375,11 +378,14 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,

if (ctx->state == SPU_STATE_SAVED) {
up_read(&current->mm->mmap_sem);
spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
down_read(&current->mm->mmap_sem);
} else {
area = ctx->spu->problem_phys + ps_offs;
vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
}

spu_release(ctx);
Expand Down
28 changes: 21 additions & 7 deletions arch/powerpc/platforms/cell/spufs/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/pid_namespace.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/marker.h>

#include <asm/io.h>
#include <asm/mmu_context.h>
Expand Down Expand Up @@ -216,8 +217,8 @@ void do_notify_spus_active(void)
*/
static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
{
pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
spu->number, spu->node);
spu_context_trace(spu_bind_context__enter, ctx, spu);

spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);

if (ctx->flags & SPU_CREATE_NOSCHED)
Expand Down Expand Up @@ -399,8 +400,8 @@ static int has_affinity(struct spu_context *ctx)
*/
static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
{
pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
spu->pid, spu->number, spu->node);
spu_context_trace(spu_unbind_context__enter, ctx, spu);

spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);

if (spu->ctx->flags & SPU_CREATE_NOSCHED)
Expand Down Expand Up @@ -528,6 +529,8 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
struct spu *spu, *aff_ref_spu;
int node, n;

spu_context_nospu_trace(spu_get_idle__enter, ctx);

if (ctx->gang) {
mutex_lock(&ctx->gang->aff_mutex);
if (has_affinity(ctx)) {
Expand All @@ -546,8 +549,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
if (atomic_dec_and_test(&ctx->gang->aff_sched_count))
ctx->gang->aff_ref_spu = NULL;
mutex_unlock(&ctx->gang->aff_mutex);

return NULL;
goto not_found;
}
mutex_unlock(&ctx->gang->aff_mutex);
}
Expand All @@ -565,12 +567,14 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
mutex_unlock(&cbe_spu_info[node].list_mutex);
}

not_found:
spu_context_nospu_trace(spu_get_idle__not_found, ctx);
return NULL;

found:
spu->alloc_state = SPU_USED;
mutex_unlock(&cbe_spu_info[node].list_mutex);
pr_debug("Got SPU %d %d\n", spu->number, spu->node);
spu_context_trace(spu_get_idle__found, ctx, spu);
spu_init_channels(spu);
return spu;
}
Expand All @@ -587,6 +591,8 @@ static struct spu *find_victim(struct spu_context *ctx)
struct spu *spu;
int node, n;

spu_context_nospu_trace(spu_find_vitim__enter, ctx);

/*
* Look for a possible preemption candidate on the local node first.
* If there is no candidate look at the other nodes. This isn't
Expand Down Expand Up @@ -640,6 +646,8 @@ static struct spu *find_victim(struct spu_context *ctx)
goto restart;
}

spu_context_trace(__spu_deactivate__unload, ctx, spu);

mutex_lock(&cbe_spu_info[node].list_mutex);
cbe_spu_info[node].nr_active--;
spu_unbind_context(spu, victim);
Expand Down Expand Up @@ -822,6 +830,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
*/
void spu_deactivate(struct spu_context *ctx)
{
spu_context_nospu_trace(spu_deactivate__enter, ctx);
__spu_deactivate(ctx, 1, MAX_PRIO);
}

Expand All @@ -835,6 +844,7 @@ void spu_deactivate(struct spu_context *ctx)
*/
void spu_yield(struct spu_context *ctx)
{
spu_context_nospu_trace(spu_yield__enter, ctx);
if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
mutex_lock(&ctx->state_mutex);
__spu_deactivate(ctx, 0, MAX_PRIO);
Expand Down Expand Up @@ -864,11 +874,15 @@ static noinline void spusched_tick(struct spu_context *ctx)
goto out;

spu = ctx->spu;

spu_context_trace(spusched_tick__preempt, ctx, spu);

new = grab_runnable_context(ctx->prio + 1, spu->node);
if (new) {
spu_unschedule(spu, ctx);
spu_add_to_rq(ctx);
} else {
spu_context_nospu_trace(spusched_tick__newslice, ctx);
ctx->time_slice++;
}
out:
Expand Down
5 changes: 5 additions & 0 deletions arch/powerpc/platforms/cell/spufs/spufs.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,9 @@ extern void spu_free_lscsa(struct spu_state *csa);
extern void spuctx_switch_state(struct spu_context *ctx,
enum spu_utilization_state new_state);

#define spu_context_trace(name, ctx, spu) \
trace_mark(name, "%p %p", ctx, spu);
#define spu_context_nospu_trace(name, ctx) \
trace_mark(name, "%p", ctx);

#endif
Loading

0 comments on commit 038200c

Please sign in to comment.