summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-06-29 10:57:55 +1000
committerPaul Mackerras <paulus@samba.org>2007-07-03 15:24:45 +1000
commit2cf2b3b49f10d2f4a0703070fc54ce1cd84a6cda (patch)
treed8b19ec2df628df8b5b10e2ac4576c28d51b9548 /arch/powerpc/platforms
parentf3f59bec0c7ad083e9c95a550bcb1e9ca27e25f4 (diff)
[POWERPC] spusched: Update scheduling paramters on every spu_run
Update scheduling information on every spu_run to allow for setting threads to realtime priority just before running them. This requires some slightly ugly code in spufs_run_spu because we can just update the information unlocked if the spu is not runnable, but we need to acquire the active_mutex when it is runnable to protect against find_victim. This locking scheme requires opencoding spu_acquire_runnable in spufs_run_spu which actually is a nice cleanup all by itself. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c11
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c19
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c27
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
4 files changed, 45 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index c5ec7cfc24b..c778d9178e0 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -54,17 +54,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
if (gang)
spu_gang_add_ctx(gang, ctx);
- /*
- * We do our own priority calculations, so we normally want
- * ->static_prio to start with. Unfortunately thies field
- * contains junk for threads with a realtime scheduling
- * policy so we have to look at ->prio in this case.
- */
- if (rt_prio(current->prio))
- ctx->prio = current->prio;
- else
- ctx->prio = current->static_prio;
- ctx->policy = current->policy;
spu_set_timeslice(ctx);
goto out;
out_free:
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 89b02b6bfc5..4e0db6ae0d5 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -301,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
ctx->ops->master_start(ctx);
ctx->event_return = 0;
- ret = spu_acquire_runnable(ctx, 0);
- if (ret)
- return ret;
+ spu_acquire(ctx);
+ if (ctx->state == SPU_STATE_SAVED) {
+ __spu_update_sched_info(ctx);
+
+ ret = spu_activate(ctx, 0);
+ if (ret) {
+ spu_release(ctx);
+ goto out;
+ }
+ } else {
+ /*
+ * We have to update the scheduling priority under active_mutex
+ * to protect against find_victim().
+ */
+ spu_update_sched_info(ctx);
+ }
ret = spu_run_init(ctx, npc);
if (ret) {
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 002b40af4a7..3707c7fdbde 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -96,6 +96,33 @@ void spu_set_timeslice(struct spu_context *ctx)
ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio);
}
+/*
+ * Update scheduling information from the owning thread.
+ */
+void __spu_update_sched_info(struct spu_context *ctx)
+{
+ /*
+ * We do our own priority calculations, so we normally want
+ * ->static_prio to start with. Unfortunately thies field
+ * contains junk for threads with a realtime scheduling
+ * policy so we have to look at ->prio in this case.
+ */
+ if (rt_prio(current->prio))
+ ctx->prio = current->prio;
+ else
+ ctx->prio = current->static_prio;
+ ctx->policy = current->policy;
+}
+
+void spu_update_sched_info(struct spu_context *ctx)
+{
+ int node = ctx->spu->node;
+
+ mutex_lock(&spu_prio->active_mutex[node]);
+ __spu_update_sched_info(ctx);
+ mutex_unlock(&spu_prio->active_mutex[node]);
+}
+
static inline int node_allowed(int node)
{
cpumask_t mask;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index fddc59c204b..ff77f904fa3 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -195,6 +195,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags);
void spu_deactivate(struct spu_context *ctx);
void spu_yield(struct spu_context *ctx);
void spu_set_timeslice(struct spu_context *ctx);
+void spu_update_sched_info(struct spu_context *ctx);
+void __spu_update_sched_info(struct spu_context *ctx);
int __init spu_sched_init(void);
void __exit spu_sched_exit(void);