[Cbe-oss-dev] [PATCH 07/21] spusched: update scheduling paramters on every spu_run

Jeremy Kerr jk at ozlabs.org
Fri Jun 29 10:57:55 EST 2007


From: Christoph Hellwig <hch at lst.de>

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 at lst.de>
Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
---
 arch/powerpc/platforms/cell/spufs/context.c |   11 -----------
 arch/powerpc/platforms/cell/spufs/run.c     |   19 ++++++++++++++++---
 arch/powerpc/platforms/cell/spufs/sched.c   |   27 +++++++++++++++++++++++++++
 arch/powerpc/platforms/cell/spufs/spufs.h   |    2 ++
 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 c5ec7cf..c778d91 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 89b02b6..4e0db6a 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 002b40a..3707c7f 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 fddc59c..ff77f90 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);
 
-- 
1.5.0.rc4.g85b1




More information about the cbe-oss-dev mailing list