[Cbe-oss-dev] [PATCH] spufs: marker-based tracing facility
Christoph Hellwig
hch at lst.de
Tue Dec 4 01:56:08 EST 2007
On Tue, Nov 27, 2007 at 07:55:19PM +0100, Christoph Hellwig wrote:
> 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.
The version I posted didn't apply ontop of the interruptible state_mutex
patch, so here's an updared version that does:
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/Makefile
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/Makefile 2007-12-03 12:20:32.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/Makefile 2007-12-03 12:20:50.000000000 +0100
@@ -4,6 +4,8 @@ spufs-y += inode.o file.o context.o sysc
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
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c 2007-12-03 12:20:45.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c 2007-12-03 12:20:50.000000000 +0100
@@ -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>
@@ -239,8 +240,8 @@ EXPORT_SYMBOL_GPL(spu_switch_event_unreg
*/
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)
@@ -422,8 +423,8 @@ static int has_affinity(struct spu_conte
*/
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)
@@ -551,6 +552,8 @@ static struct spu *spu_get_idle(struct s
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)) {
@@ -569,8 +572,7 @@ static struct spu *spu_get_idle(struct s
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);
}
@@ -588,12 +590,14 @@ static struct spu *spu_get_idle(struct s
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;
}
@@ -610,6 +614,8 @@ static struct spu *find_victim(struct sp
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
@@ -663,6 +669,8 @@ static struct spu *find_victim(struct sp
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);
@@ -845,6 +853,7 @@ static int __spu_deactivate(struct spu_c
*/
void spu_deactivate(struct spu_context *ctx)
{
+ spu_context_nospu_trace(spu_deactivate__enter, ctx);
__spu_deactivate(ctx, 1, MAX_PRIO);
}
@@ -858,6 +867,7 @@ void spu_deactivate(struct spu_context *
*/
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);
@@ -887,11 +897,15 @@ static noinline void spusched_tick(struc
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:
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sputrace.c 2007-12-03 12:20:32.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c 2007-12-03 12:20:50.000000000 +0100
@@ -146,10 +146,10 @@ static void sputrace_log_item(const char
wake_up(&sputrace_wait);
}
-static void spu_context_event(const struct __mark_marker *mdata,
+static void spu_context_event(const struct marker *mdata,
void *private, const char *format, ...)
{
- struct spu_probe *p = mdata->pdata;
+ struct spu_probe *p = mdata->private;
va_list ap;
struct spu_context *ctx;
struct spu *spu;
@@ -162,10 +162,10 @@ static void spu_context_event(const stru
va_end(ap);
}
-static void spu_context_nospu_event(const struct __mark_marker *mdata,
+static void spu_context_nospu_event(const struct marker *mdata,
void *private, const char *format, ...)
{
- struct spu_probe *p = mdata->pdata;
+ struct spu_probe *p = mdata->private;
va_list ap;
struct spu_context *ctx;
@@ -184,7 +184,6 @@ struct spu_probe spu_probes[] = {
{ "spu_get_idle__not_found", "%p", spu_context_nospu_event },
{ "spu_find_victim__enter", "%p", spu_context_nospu_event },
{ "spusched_tick__preempt", "%p %p", spu_context_event },
- { "spusched_tick__preempt_failed", "%p %p", spu_context_event },
{ "spusched_tick__newslice", "%p", spu_context_nospu_event },
{ "spu_yield__enter", "%p", spu_context_nospu_event },
{ "spu_deactivate__enter", "%p", spu_context_nospu_event },
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c 2007-12-03 12:20:45.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c 2007-12-03 12:21:58.000000000 +0100
@@ -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>
@@ -358,6 +359,8 @@ static unsigned long spufs_ps_nopfn(stru
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;
@@ -375,11 +378,14 @@ static unsigned long spufs_ps_nopfn(stru
if (ctx->state == SPU_STATE_SAVED) {
up_read(¤t->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(¤t->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);
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/spufs.h 2007-12-03 12:20:45.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h 2007-12-03 12:20:50.000000000 +0100
@@ -325,4 +325,9 @@ extern void spu_free_lscsa(struct spu_st
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
Index: linux-2.6/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/Kconfig 2007-12-03 12:20:32.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/Kconfig 2007-12-03 12:20:50.000000000 +0100
@@ -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
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c.rej
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c.rej 2007-12-03 12:21:01.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-*************** static unsigned long spufs_ps_nopfn(stru
-*** 373,385 ****
- spu_acquire(ctx);
- if (ctx->state == SPU_STATE_SAVED) {
- up_read(¤t->mm->mmap_sem);
- spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
- down_read(¤t->mm->mmap_sem);
- goto out;
- }
-
- area = ctx->spu->problem_phys + ps_offs;
- vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
-
- out:
- spu_release(ctx);
---- 376,391 ----
- spu_acquire(ctx);
- if (ctx->state == SPU_STATE_SAVED) {
- up_read(¤t->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(¤t->mm->mmap_sem);
- goto out;
- }
-
- 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);
-
- out:
- spu_release(ctx);
More information about the cbe-oss-dev
mailing list