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

Commit 038200cf authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Paul Mackerras
Browse files

[POWERPC] spufs: Add marker-based tracing facility



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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 551e4fb2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -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(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;
@@ -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);
+21 −7
Original line number Diff line number Diff line
@@ -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>
@@ -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)
@@ -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)
@@ -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)) {
@@ -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);
	}
@@ -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;
}
@@ -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
@@ -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);
@@ -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);
}

@@ -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);
@@ -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:
+5 −0
Original line number Diff line number Diff line
@@ -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