[Cbe-oss-dev] [PATCH 5:7] spufs: fix synchronization of class 1 exception data [Updated]

Luke Browning lukebr at linux.vnet.ibm.com
Thu May 15 10:36:33 EST 2008


Fix synchronization of class 1 exception state.

Exception state is produced in the interrupt handler and 
consumed at the thread locking.  Memory barriers are used to
atomically share this information.  The clearing of this state 
must be carefully managed so that it does not overwrite new
exception data.  The clear must be followed by a synch 
instruction before the dma restart is performed.  Otherwise,
it might be scheduled out of order by the processor after 
the store restart operation which takes affect immediately. 
This might cause us to lose a class 1 exception in theory.

Also, restarting dma does not depend on the whether the 
context is currently loaded.  The saved state of the mfc control 
register must be updated to restart the dma.  This takes affect
when the context is resumed.

Update: fixed synch instruction in run.c.  eieio is for non-cached memory.

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

--

Index: spufs/arch/powerpc/platforms/cell/spufs/fault.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/fault.c
+++ spufs/arch/powerpc/platforms/cell/spufs/fault.c
@@ -122,7 +122,7 @@ int spufs_handle_class1(struct spu_conte
 	 *
 	 * if we don't handle the fault for a saved context
 	 * in time, we can still expect to get the same fault
-	 * the immediately after the context restore.
+	 * immediately after the context restore.
 	 */
 	ea = ctx->csa.class_1_dar;
 	dsisr = ctx->csa.class_1_dsisr;
@@ -159,11 +159,12 @@ int spufs_handle_class1(struct spu_conte
 	mutex_lock(&ctx->state_mutex);
 
 	/*
-	 * Clear dsisr under ctxt lock after handling the fault, so that
-	 * time slicing will not preempt the context while the page fault
-	 * handler is running. Context switch code removes mappings.
+	 * Clear the exception fields in the csa before restarting the dma.  The
+	 * interrupt handler sets these fields without a lock, so we must clear
+	 * them at a point where we know a new exception cannot be generated.
 	 */
 	ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0;
+	smp_wmb();
 
 	/*
 	 * If we handled the fault successfully and are in runnable
@@ -181,9 +182,7 @@ int spufs_handle_class1(struct spu_conte
 			else
 				ctx->spu->stats.min_flt++;
 		}
-
-		if (ctx->spu)
-			ctx->ops->restart_dma(ctx);
+		ctx->ops->restart_dma(ctx);
 	} else
 		spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
 
Index: spufs/arch/powerpc/platforms/cell/spufs/run.c
===================================================================
--- spufs.orig/arch/powerpc/platforms/cell/spufs/run.c
+++ spufs/arch/powerpc/platforms/cell/spufs/run.c
@@ -47,7 +47,7 @@ void spufs_stop_callback(struct spu *spu
 		 * Ensure that the exception status has hit memory before a
 		 * thread waiting on the context's stop queue is woken
 		 */
-		smp_wmb();
+		smp_mb();
 
 		wake_up_all(&ctx->stop_wq);
 	}





More information about the cbe-oss-dev mailing list