aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spufs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/inode.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 9e457be140e..1fbcc536924 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -248,8 +248,13 @@ static int spu_setup_isolated(struct spu_context *ctx)
if (!isolated_loader)
return -ENODEV;
- if ((ret = spu_acquire_exclusive(ctx)) != 0)
- return ret;
+ /* prevent concurrent operation with spu_run */
+ down(&ctx->run_sema);
+ ctx->ops->master_start(ctx);
+
+ ret = spu_acquire_exclusive(ctx);
+ if (ret)
+ goto out;
mfc_cntl = &ctx->spu->priv2->mfc_control_RW;
@@ -315,12 +320,14 @@ out_drop_priv:
out_unlock:
spu_release_exclusive(ctx);
+out:
+ ctx->ops->master_stop(ctx);
+ up(&ctx->run_sema);
return ret;
}
int spu_recycle_isolated(struct spu_context *ctx)
{
- ctx->ops->runcntl_stop(ctx);
return spu_setup_isolated(ctx);
}
@@ -435,6 +442,8 @@ out:
if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) {
int setup_err = spu_setup_isolated(
SPUFS_I(dentry->d_inode)->i_ctx);
+ /* FIXME: clean up context again on failure to avoid
+ leak. */
if (setup_err)
ret = setup_err;
}