[Cbe-oss-dev] [PATCH] spufs: rework list management and associated locking

Christoph Hellwig hch at lst.de
Fri Jul 20 22:06:52 EST 2007


As it turns out the SPU_FREE check is not enough protection for the
timer_tick.  spu can have no context associated for a short time
during a context switch without officially beeing freed.  That means
we need to check spu->ctx before setting it in spusched_thread and
take the list_lock over all context switches.  This means all context
switches for a single node are serialized now, but this shouldn't be
too bad because the main source of context switches is the schedule
thread which is implizitly serializing it's context switches anyway.


Signed-off-by: Christoph Hellwig <hch at lst.de>

Index: linux-cell/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/spufs/sched.c	2007-07-20 12:54:49.000000000 +0200
+++ linux-cell/arch/powerpc/platforms/cell/spufs/sched.c	2007-07-20 12:59:51.000000000 +0200
@@ -661,9 +661,8 @@ int spu_activate(struct spu_context *ctx
 		if (spu) {
 			int node = spu->node;
 
-			spu_bind_context(spu, ctx);
-
 			mutex_lock(&cbe_spu_info[node].list_mutex);
+			spu_bind_context(spu, ctx);
 			cbe_spu_info[node].nr_active++;
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 			return 0;
@@ -716,15 +715,15 @@ static int __spu_deactivate(struct spu_c
 		if (new || force) {
 			int node = spu->node;
 
-			spu_unbind_context(spu, ctx);
-			ctx->stats.vol_ctx_switch++;
-			spu->stats.vol_ctx_switch++;
-
 			mutex_lock(&cbe_spu_info[node].list_mutex);
+			spu_unbind_context(spu, ctx);
 			spu->alloc_state = SPU_FREE;
 			cbe_spu_info[node].nr_active--;
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 
+			ctx->stats.vol_ctx_switch++;
+			spu->stats.vol_ctx_switch++;
+
 			if (new)
 				wake_up(&new->stop_wq);
 		}
@@ -867,7 +866,7 @@ static int spusched_thread(void *unused)
 		for (node = 0; node < MAX_NUMNODES; node++) {
 			mutex_lock(&cbe_spu_info[node].list_mutex);
 			list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list)
-				if (spu->alloc_state != SPU_FREE)
+				if (spu->ctx)
 					spusched_tick(spu->ctx);
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 		}



More information about the cbe-oss-dev mailing list