[Cbe-oss-dev] [PATCH 3/6] spufs: fix starvation case with terminated spes

Luke Browning lukebr at linux.vnet.ibm.com
Thu Feb 7 04:43:33 EST 2008


Fix spu starvation case with terminated ctxts.

Terminated spe contexts need to yield the spu, so that the spufs scheduler
can service the runqueue.  Can't rely on the libspe to destroy the context 
as it is not a trusted entity.  Fixes a testcase where a program creates 
100 standalone contexts (ie. gang of one) and then waits for them to 
complete before it starts to destroy contexts. 

Moved spu_yield() into spu_run_fini() to avoid the extra lock reference. 

Signed-off-by: Luke Browning <lukebrowning at us.ibm.com>
---

Index: spufs/arch/powerpc/platforms/cell/spufs/run.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/run.c	2008-02-06 12:46:01.000000000 -0200
+++ spufs/arch/powerpc/platforms/cell/spufs/run.c	2008-02-06 12:48:22.000000000 -0200
@@ -234,6 +234,9 @@
 	*npc = ctx->ops->npc_read(ctx);
 
 	spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
+
+	__spu_yield(ctx);
+
 	spu_release(ctx);
 
 	if (signal_pending(current))
@@ -400,10 +403,8 @@
 	    (ctx->state == SPU_STATE_RUNNABLE))
 		ctx->stats.libassist++;
 
-
 	spu_disable_spu(ctx);
 	ret = spu_run_fini(ctx, npc, &status);
-	spu_yield(ctx);
 
 	if ((ret == 0) ||
 	    ((ret == -ERESTARTSYS) &&
Index: spufs/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/sched.c	2008-02-06 12:43:41.000000000 -0200
+++ spufs/arch/powerpc/platforms/cell/spufs/sched.c	2008-02-06 12:48:22.000000000 -0200
@@ -848,6 +848,20 @@
 	__spu_deactivate(ctx, 1, MAX_PRIO);
 }
 
+void __spu_yield(struct spu_context *ctx)
+{
+	if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
+		int force;
+		u32 status = ctx->ops->status_read(ctx);
+
+		if (status >> SPU_STOP_STATUS_SHIFT == 0x2000) /* PROGRAM END */
+			force = 1;
+		else
+			force = 0;
+		__spu_deactivate(ctx, force, MAX_PRIO);
+	}
+}
+
 /**
  * spu_yield -	yield a physical spu if others are waiting
  * @ctx:	spu context to yield
@@ -858,11 +872,9 @@
  */
 void spu_yield(struct spu_context *ctx)
 {
-	if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
-		mutex_lock(&ctx->state_mutex);
-		__spu_deactivate(ctx, 0, MAX_PRIO);
-		mutex_unlock(&ctx->state_mutex);
-	}
+	mutex_lock(&ctx->state_mutex);
+	__spu_yield(ctx);
+	mutex_unlock(&ctx->state_mutex);
 }
 
 static noinline void spusched_tick(struct spu_context *ctx)
Index: spufs/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/spufs.h	2008-02-06 12:43:41.000000000 -0200
+++ spufs/arch/powerpc/platforms/cell/spufs/spufs.h	2008-02-06 12:48:22.000000000 -0200
@@ -253,6 +253,7 @@
 void spu_del_from_rq(struct spu_context *ctx);
 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_yield(struct spu_context *ctx);
 void spu_switch_notify(struct spu *spu, struct spu_context *ctx);
 void spu_set_timeslice(struct spu_context *ctx);





More information about the cbe-oss-dev mailing list