[Cbe-oss-dev] [PATCH 10/10] spu sched: avoid superflous wakeups in spu_run

Christoph Hellwig hch at lst.de
Mon Jan 8 09:15:37 EST 2007


There is no need to directly wake up contexts in spu_activate when
called from spu_run, so add a flag to surpress this wakeup.


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

Index: linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/spufs.h	2007-01-07 21:53:39.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h	2007-01-07 21:53:39.000000000 +0100
@@ -40,6 +40,11 @@
 struct spu_context_ops;
 struct spu_gang;
 
+/* ctx->sched_flags */
+enum {
+	SPU_SCHED_WAKE = 0,
+};
+
 struct spu_context {
 	struct spu *spu;		  /* pointer to a physical SPU */
 	struct spu_state csa;		  /* SPU context save area. */
@@ -76,6 +81,7 @@
 
 	/* scheduler fields */
  	struct list_head rq;
+	unsigned long sched_flags;
 	int prio;
 };
 
@@ -188,10 +194,13 @@
 void spu_unmap_mappings(struct spu_context *ctx);
 
 void spu_forget(struct spu_context *ctx);
-int spu_acquire_runnable(struct spu_context *ctx);
+int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
 void spu_acquire_saved(struct spu_context *ctx);
 int spu_acquire_exclusive(struct spu_context *ctx);
-int spu_activate(struct spu_context *ctx, u64 flags);
+enum {
+	SPU_ACTIVATE_NOWAKE = 1,
+};
+int spu_activate(struct spu_context *ctx, unsigned long flags);
 void spu_deactivate(struct spu_context *ctx);
 void spu_yield(struct spu_context *ctx);
 int __init spu_sched_init(void);
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c	2007-01-07 21:53:39.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c	2007-01-07 21:53:39.000000000 +0100
@@ -261,8 +261,8 @@
 {
 	DEFINE_WAIT(wait);
 
+	set_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
 	prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE);
-
 	if (!signal_pending(current)) {
 		mutex_unlock(&ctx->state_mutex);
 		schedule();
@@ -270,6 +270,7 @@
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctx->stop_wq, &wait);
+	clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
 }
 
 /**
@@ -289,7 +290,7 @@
 	best = sched_find_first_bit(spu_prio->bitmap);
 	if (best < MAX_PRIO) {
 		struct spu_context *ctx = spu_grab_context(best);
-		if (ctx)
+		if (ctx && test_bit(SPU_SCHED_WAKE, &ctx->sched_flags))
 			wake_up(&ctx->stop_wq);
 	}
 	mutex_unlock(&spu_prio->mutex);
@@ -329,7 +330,7 @@
  * add the context to the runqueue so it gets woken up once an spu
  * is available.
  */
-int spu_activate(struct spu_context *ctx, u64 flags)
+int spu_activate(struct spu_context *ctx, unsigned long flags)
 {
 
 	if (ctx->spu)
@@ -345,7 +346,8 @@
 		}
 
 		spu_add_to_rq(ctx);
-		spu_prio_wait(ctx);
+		if (!(flags & SPU_ACTIVATE_NOWAKE))
+			spu_prio_wait(ctx);
 	} while (!signal_pending(current));
 
 
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/context.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/context.c	2007-01-07 21:53:38.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/context.c	2007-01-07 21:53:39.000000000 +0100
@@ -159,7 +159,7 @@
  *	Returns 0 and with the context locked on success
  *	Returns negative error and with the context _unlocked_ on failure.
  */
-int spu_acquire_runnable(struct spu_context *ctx)
+int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags)
 {
 	int ret = -EINVAL;
 
@@ -170,7 +170,7 @@
 		 */
 		if (!ctx->owner)
 			goto out_unlock;
-		ret = spu_activate(ctx, 0);
+		ret = spu_activate(ctx, flags);
 		if (ret)
 			goto out_unlock;
 	}
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c	2007-01-04 23:14:46.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c	2007-01-07 21:53:39.000000000 +0100
@@ -168,7 +168,7 @@
 	if (offset >= ps_size)
 		goto out;
 
-	ret = spu_acquire_runnable(ctx);
+	ret = spu_acquire_runnable(ctx, 0);
 	if (ret)
 		goto out;
 
@@ -1309,7 +1309,7 @@
 	if (ret)
 		goto out;
 
-	spu_acquire_runnable(ctx);
+	spu_acquire_runnable(ctx, 0);
 	if (file->f_flags & O_NONBLOCK) {
 		ret = ctx->ops->send_mfc_command(ctx, &cmd);
 	} else {
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/run.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/run.c	2007-01-07 21:53:36.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/run.c	2007-01-07 22:46:07.000000000 +0100
@@ -143,7 +143,7 @@
 	int ret;
 	unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
 
-	ret = spu_acquire_runnable(ctx);
+	ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE);
 	if (ret)
 		return ret;
 
@@ -155,7 +155,7 @@
 			spu_release(ctx);
 			ret = spu_setup_isolated(ctx);
 			if (!ret)
-				ret = spu_acquire_runnable(ctx);
+				ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE);
 		}
 
 		/* if userspace has set the runcntrl register (eg, to issue an



More information about the cbe-oss-dev mailing list