diff options
author | Arnd Bergmann <arnd@arndb.de> | 2006-01-04 14:31:24 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 23:44:39 -0500 |
commit | 5ef8224aaa9220bfecb362f0802cf78aad47c02a (patch) | |
tree | 3288b9510d4ab36d627cf85f1b4160a6d8ff9823 | |
parent | e80358ad8606382154d97165121602dfae213e4a (diff) |
[PATCH] spufs: serialize sys_spu_run per spu
During an earlier cleanup, we lost the serialization
of multiple spu_run calls performed on the same
spu_context. In order to get this back, introduce a
mutex in the spu_context that is held inside of spu_run.
Noticed by Al Viro.
Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 15 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 1 |
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) | |||
43 | spin_lock_init(&ctx->mmio_lock); | 43 | spin_lock_init(&ctx->mmio_lock); |
44 | kref_init(&ctx->kref); | 44 | kref_init(&ctx->kref); |
45 | init_rwsem(&ctx->state_sema); | 45 | init_rwsem(&ctx->state_sema); |
46 | init_MUTEX(&ctx->run_sema); | ||
46 | init_waitqueue_head(&ctx->ibox_wq); | 47 | init_waitqueue_head(&ctx->ibox_wq); |
47 | init_waitqueue_head(&ctx->wbox_wq); | 48 | init_waitqueue_head(&ctx->wbox_wq); |
48 | init_waitqueue_head(&ctx->stop_wq); | 49 | 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, | |||
620 | { | 620 | { |
621 | int ret; | 621 | int ret; |
622 | 622 | ||
623 | if ((ret = spu_run_init(ctx, npc, status)) != 0) | 623 | if (down_interruptible(&ctx->run_sema)) |
624 | return ret; | 624 | return -ERESTARTSYS; |
625 | |||
626 | ret = spu_run_init(ctx, npc, status); | ||
627 | if (ret) | ||
628 | goto out; | ||
625 | 629 | ||
626 | do { | 630 | do { |
627 | ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); | 631 | 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, | |||
629 | break; | 633 | break; |
630 | if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { | 634 | if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { |
631 | ret = spu_reacquire_runnable(ctx, npc, status); | 635 | ret = spu_reacquire_runnable(ctx, npc, status); |
632 | if (ret) { | 636 | if (ret) |
633 | return ret; | 637 | goto out; |
634 | } | ||
635 | continue; | 638 | continue; |
636 | } | 639 | } |
637 | ret = spu_process_events(ctx); | 640 | ret = spu_process_events(ctx); |
@@ -645,6 +648,8 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, | |||
645 | ret = *status; | 648 | ret = *status; |
646 | spu_yield(ctx); | 649 | spu_yield(ctx); |
647 | 650 | ||
651 | out: | ||
652 | up(&ctx->run_sema); | ||
648 | return ret; | 653 | return ret; |
649 | } | 654 | } |
650 | 655 | ||
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 { | |||
48 | 48 | ||
49 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; | 49 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; |
50 | struct rw_semaphore state_sema; | 50 | struct rw_semaphore state_sema; |
51 | struct semaphore run_sema; | ||
51 | 52 | ||
52 | struct mm_struct *owner; | 53 | struct mm_struct *owner; |
53 | 54 | ||