[Cbe-oss-dev] [PATCH 6/10] spu sched: switch state_sema to a mutex

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


The r/w semaphore to lock the spus was overkill and can be replaced
with a mutex to make it faster, simpler and easier to debug.  It also
helps to allow making most spufs interruptible in future patches.


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

Index: linux-2.6/arch/powerpc/platforms/cell/spufs/context.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/context.c	2007-01-03 19:27:09.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/context.c	2007-01-03 19:45:55.000000000 +0100
@@ -42,7 +42,7 @@
 	}
 	spin_lock_init(&ctx->mmio_lock);
 	kref_init(&ctx->kref);
-	init_rwsem(&ctx->state_sema);
+	mutex_init(&ctx->state_mutex);
 	init_MUTEX(&ctx->run_sema);
 	init_waitqueue_head(&ctx->ibox_wq);
 	init_waitqueue_head(&ctx->wbox_wq);
@@ -65,9 +65,9 @@
 {
 	struct spu_context *ctx;
 	ctx = container_of(kref, struct spu_context, kref);
-	down_write(&ctx->state_sema);
+	mutex_lock(&ctx->state_mutex);
 	spu_deactivate(ctx);
-	up_write(&ctx->state_sema);
+	mutex_unlock(&ctx->state_mutex);
 	spu_fini_csa(&ctx->csa);
 	if (ctx->gang)
 		spu_gang_remove_ctx(ctx->gang, ctx);
@@ -98,12 +98,12 @@
 
 void spu_acquire(struct spu_context *ctx)
 {
-	down_read(&ctx->state_sema);
+	mutex_lock(&ctx->state_mutex);
 }
 
 void spu_release(struct spu_context *ctx)
 {
-	up_read(&ctx->state_sema);
+	mutex_unlock(&ctx->state_mutex);
 }
 
 void spu_unmap_mappings(struct spu_context *ctx)
@@ -124,7 +124,7 @@
 {
 	int ret = 0;
 
-	down_write(&ctx->state_sema);
+	mutex_lock(&ctx->state_mutex);
 	/* ctx is about to be freed, can't acquire any more */
 	if (!ctx->owner) {
 		ret = -EINVAL;
@@ -142,7 +142,7 @@
 
 out:
 	if (ret)
-		up_write(&ctx->state_sema);
+		mutex_unlock(&ctx->state_mutex);
 	return ret;
 }
 
@@ -150,14 +150,12 @@
 {
 	int ret = 0;
 
-	down_read(&ctx->state_sema);
+	mutex_lock(&ctx->state_mutex);
 	if (ctx->state == SPU_STATE_RUNNABLE) {
 		ctx->spu->prio = current->prio;
 		return 0;
 	}
-	up_read(&ctx->state_sema);
 
-	down_write(&ctx->state_sema);
 	/* ctx is about to be freed, can't acquire any more */
 	if (!ctx->owner) {
 		ret = -EINVAL;
@@ -170,29 +168,18 @@
 			goto out;
 	}
 
-	downgrade_write(&ctx->state_sema);
 	/* On success, we return holding the lock */
-
 	return ret;
 out:
 	/* Release here, to simplify calling code. */
-	up_write(&ctx->state_sema);
+	mutex_unlock(&ctx->state_mutex);
 
 	return ret;
 }
 
 void spu_acquire_saved(struct spu_context *ctx)
 {
-	down_read(&ctx->state_sema);
-
-	if (ctx->state == SPU_STATE_SAVED)
-		return;
-
-	up_read(&ctx->state_sema);
-	down_write(&ctx->state_sema);
-
+	mutex_lock(&ctx->state_mutex);
 	if (ctx->state == SPU_STATE_RUNNABLE)
 		spu_deactivate(ctx);
-
-	downgrade_write(&ctx->state_sema);
 }
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c	2007-01-03 19:27:09.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c	2007-01-03 19:45:18.000000000 +0100
@@ -233,11 +233,11 @@
 	spu_add_wq(wq, &wait, prio);
 
 	if (!signal_pending(current)) {
-		up_write(&ctx->state_sema);
+		mutex_unlock(&ctx->state_mutex);
 		pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
 			 current->pid, current->prio);
 		schedule();
-		down_write(&ctx->state_sema);
+		mutex_lock(&ctx->state_mutex);
 	}
 
 	spu_del_wq(wq, &wait, prio);
@@ -334,7 +334,7 @@
 	struct spu *spu;
 	int need_yield = 0;
 
-	if (down_write_trylock(&ctx->state_sema)) {
+	if (mutex_trylock(&ctx->state_mutex)) {
 		if ((spu = ctx->spu) != NULL) {
 			int best = sched_find_first_bit(spu_prio->bitmap);
 			if (best < MAX_PRIO) {
@@ -346,7 +346,7 @@
 				spu->prio = MAX_PRIO;
 			}
 		}
-		up_write(&ctx->state_sema);
+		mutex_unlock(&ctx->state_mutex);
 	}
 	if (unlikely(need_yield))
 		yield();
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/spufs.h	2007-01-03 19:27:09.000000000 +0100
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h	2007-01-03 19:31:29.000000000 +0100
@@ -23,7 +23,7 @@
 #define SPUFS_H
 
 #include <linux/kref.h>
-#include <linux/rwsem.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 
@@ -51,7 +51,7 @@
 	u64 object_id;		   /* user space pointer for oprofile */
 
 	enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
-	struct rw_semaphore state_sema;
+	struct mutex state_mutex;
 	struct semaphore run_sema;
 
 	struct mm_struct *owner;
@@ -171,7 +171,7 @@
 
 static inline void spu_release_exclusive(struct spu_context *ctx)
 {
-	up_write(&ctx->state_sema);
+	mutex_unlock(&ctx->state_mutex);
 }
 
 int spu_activate(struct spu_context *ctx, u64 flags);



More information about the cbe-oss-dev mailing list