[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(&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);
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(&current->mm->mmap_sem);
-  		spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
-  		down_read(&current->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(&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);
-  		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