summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c15
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h1
3 files changed, 12 insertions, 5 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 903c35d19577..c5cd55ac848d 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -43,6 +43,7 @@ struct spu_context *alloc_spu_context(struct address_space *local_store)
spin_lock_init(&ctx->mmio_lock);
kref_init(&ctx->kref);
init_rwsem(&ctx->state_sema);
+ init_MUTEX(&ctx->run_sema);
init_waitqueue_head(&ctx->ibox_wq);
init_waitqueue_head(&ctx->wbox_wq);
init_waitqueue_head(&ctx->stop_wq);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 9738de727f32..e63426822fd5 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -620,8 +620,12 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
{
int ret;
- if ((ret = spu_run_init(ctx, npc, status)) != 0)
- return ret;
+ if (down_interruptible(&ctx->run_sema))
+ return -ERESTARTSYS;
+
+ ret = spu_run_init(ctx, npc, status);
+ if (ret)
+ goto out;
do {
ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
@@ -629,9 +633,8 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
break;
if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
ret = spu_reacquire_runnable(ctx, npc, status);
- if (ret) {
- return ret;
- }
+ if (ret)
+ goto out;
continue;
}
ret = spu_process_events(ctx);
@@ -645,6 +648,8 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
ret = *status;
spu_yield(ctx);
+out:
+ up(&ctx->run_sema);
return ret;
}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 420953b58881..b50474450819 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -48,6 +48,7 @@ struct spu_context {
enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
struct rw_semaphore state_sema;
+ struct semaphore run_sema;
struct mm_struct *owner;