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

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

[POWERPC] spufs: Add spu stats in sysfs



Export spu statistics in sysfs.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 27449971
Loading
Loading
Loading
Loading
+44 −0
Original line number Original line Diff line number Diff line
@@ -585,6 +585,9 @@ static int __init create_spu(void *data)
	spin_unlock_irqrestore(&spu_list_lock, flags);
	spin_unlock_irqrestore(&spu_list_lock, flags);
	mutex_unlock(&spu_mutex);
	mutex_unlock(&spu_mutex);


	spu->stats.utilization_state = SPU_UTIL_IDLE;
	spu->stats.tstamp = jiffies;

	goto out;
	goto out;


out_free_irqs:
out_free_irqs:
@@ -597,6 +600,45 @@ static int __init create_spu(void *data)
	return ret;
	return ret;
}
}


static const char *spu_state_names[] = {
	"user", "system", "iowait", "idle"
};

static unsigned long long spu_acct_time(struct spu *spu,
		enum spu_utilization_state state)
{
	unsigned long long time = spu->stats.times[state];

	if (spu->stats.utilization_state == state)
		time += jiffies - spu->stats.tstamp;

	return jiffies_to_msecs(time);
}


static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
{
	struct spu *spu = container_of(sysdev, struct spu, sysdev);

	return sprintf(buf, "%s %llu %llu %llu %llu "
		      "%llu %llu %llu %llu %llu %llu %llu %llu\n",
		spu_state_names[spu->stats.utilization_state],
		spu_acct_time(spu, SPU_UTIL_USER),
		spu_acct_time(spu, SPU_UTIL_SYSTEM),
		spu_acct_time(spu, SPU_UTIL_IOWAIT),
		spu_acct_time(spu, SPU_UTIL_IDLE),
		spu->stats.vol_ctx_switch,
		spu->stats.invol_ctx_switch,
		spu->stats.slb_flt,
		spu->stats.hash_flt,
		spu->stats.min_flt,
		spu->stats.maj_flt,
		spu->stats.class2_intr,
		spu->stats.libassist);
}

static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);

static int __init init_spu_base(void)
static int __init init_spu_base(void)
{
{
	int i, ret = 0;
	int i, ret = 0;
@@ -622,6 +664,8 @@ static int __init init_spu_base(void)


	xmon_register_spus(&spu_full_list);
	xmon_register_spus(&spu_full_list);


	spu_add_sysdev_attr(&attr_stat);

	return 0;
	return 0;


 out_unregister_sysdev_class:
 out_unregister_sysdev_class:
+10 −0
Original line number Original line Diff line number Diff line
@@ -187,6 +187,10 @@ int spufs_handle_class1(struct spu_context *ctx)
		dsisr, ctx->state);
		dsisr, ctx->state);


	ctx->stats.hash_flt++;
	ctx->stats.hash_flt++;
	if (ctx->state == SPU_STATE_RUNNABLE) {
		ctx->spu->stats.hash_flt++;
		spu_switch_state(ctx->spu, SPU_UTIL_IOWAIT);
	}


	/* we must not hold the lock when entering spu_handle_mm_fault */
	/* we must not hold the lock when entering spu_handle_mm_fault */
	spu_release(ctx);
	spu_release(ctx);
@@ -212,6 +216,12 @@ int spufs_handle_class1(struct spu_context *ctx)
			ctx->stats.min_flt++;
			ctx->stats.min_flt++;
		else
		else
			ctx->stats.maj_flt++;
			ctx->stats.maj_flt++;
		if (ctx->state == SPU_STATE_RUNNABLE) {
			if (flt == VM_FAULT_MINOR)
				ctx->spu->stats.min_flt++;
			else
				ctx->spu->stats.maj_flt++;
		}


		if (ctx->spu)
		if (ctx->spu)
			ctx->ops->restart_dma(ctx);
			ctx->ops->restart_dma(ctx);
+2 −1
Original line number Original line Diff line number Diff line
@@ -352,7 +352,8 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
				       SPU_STATUS_SINGLE_STEP)));
				       SPU_STATUS_SINGLE_STEP)));


	if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
	if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
	    (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100))
	    (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100) &&
	    (ctx->state == SPU_STATE_RUNNABLE))
		ctx->stats.libassist++;
		ctx->stats.libassist++;


	ctx->ops->master_stop(ctx);
	ctx->ops->master_stop(ctx);
+9 −1
Original line number Original line Diff line number Diff line
@@ -251,6 +251,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
	spu_cpu_affinity_set(spu, raw_smp_processor_id());
	spu_cpu_affinity_set(spu, raw_smp_processor_id());
	spu_switch_notify(spu, ctx);
	spu_switch_notify(spu, ctx);
	ctx->state = SPU_STATE_RUNNABLE;
	ctx->state = SPU_STATE_RUNNABLE;
	spu_switch_state(spu, SPU_UTIL_SYSTEM);
}
}


/**
/**
@@ -263,6 +264,8 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
	pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
	pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
		 spu->pid, spu->number, spu->node);
		 spu->pid, spu->number, spu->node);


	spu_switch_state(spu, SPU_UTIL_IDLE);

	spu_switch_notify(spu, NULL);
	spu_switch_notify(spu, NULL);
	spu_unmap_mappings(ctx);
	spu_unmap_mappings(ctx);
	spu_save(&ctx->csa, spu);
	spu_save(&ctx->csa, spu);
@@ -426,6 +429,7 @@ static struct spu *find_victim(struct spu_context *ctx)
			spu_remove_from_active_list(spu);
			spu_remove_from_active_list(spu);
			spu_unbind_context(spu, victim);
			spu_unbind_context(spu, victim);
			victim->stats.invol_ctx_switch++;
			victim->stats.invol_ctx_switch++;
			spu->stats.invol_ctx_switch++;
			mutex_unlock(&victim->state_mutex);
			mutex_unlock(&victim->state_mutex);
			/*
			/*
			 * We need to break out of the wait loop in spu_run
			 * We need to break out of the wait loop in spu_run
@@ -526,6 +530,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
			spu_remove_from_active_list(spu);
			spu_remove_from_active_list(spu);
			spu_unbind_context(spu, ctx);
			spu_unbind_context(spu, ctx);
			ctx->stats.vol_ctx_switch++;
			ctx->stats.vol_ctx_switch++;
			spu->stats.vol_ctx_switch++;
			spu_free(spu);
			spu_free(spu);
			if (new)
			if (new)
				wake_up(&new->stop_wq);
				wake_up(&new->stop_wq);
@@ -572,8 +577,10 @@ void spu_yield(struct spu_context *ctx)
		mutex_lock(&ctx->state_mutex);
		mutex_lock(&ctx->state_mutex);
		if (__spu_deactivate(ctx, 0, MAX_PRIO))
		if (__spu_deactivate(ctx, 0, MAX_PRIO))
			spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
			spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
		else
		else {
			spuctx_switch_state(ctx, SPUCTX_UTIL_LOADED);
			spuctx_switch_state(ctx, SPUCTX_UTIL_LOADED);
			spu_switch_state(ctx->spu, SPU_UTIL_USER);
		}
		mutex_unlock(&ctx->state_mutex);
		mutex_unlock(&ctx->state_mutex);
	}
	}
}
}
@@ -603,6 +610,7 @@ static void spusched_tick(struct spu_context *ctx)
			__spu_remove_from_active_list(spu);
			__spu_remove_from_active_list(spu);
			spu_unbind_context(spu, ctx);
			spu_unbind_context(spu, ctx);
			ctx->stats.invol_ctx_switch++;
			ctx->stats.invol_ctx_switch++;
			spu->stats.invol_ctx_switch++;
			spu_free(spu);
			spu_free(spu);
			wake_up(&new->stop_wq);
			wake_up(&new->stop_wq);
			/*
			/*
+13 −0
Original line number Original line Diff line number Diff line
@@ -307,4 +307,17 @@ static inline void spuctx_switch_state(struct spu_context *ctx,
	}
	}
}
}


static inline void spu_switch_state(struct spu *spu,
		enum spuctx_execution_state new_state)
{
	if (spu->stats.utilization_state != new_state) {
		unsigned long curtime = jiffies;

		spu->stats.times[spu->stats.utilization_state] +=
				 curtime - spu->stats.tstamp;
		spu->stats.tstamp = curtime;
		spu->stats.utilization_state = new_state;
	}
}

#endif
#endif
Loading