diff options
Diffstat (limited to 'arch/powerpc/platforms/cell')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 23 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/coredump.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/fault.c | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 209 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 10 |
7 files changed, 219 insertions, 65 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 290b10e45105..237e152d31dc 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
@@ -106,7 +106,17 @@ int put_spu_context(struct spu_context *ctx) | |||
106 | void spu_forget(struct spu_context *ctx) | 106 | void spu_forget(struct spu_context *ctx) |
107 | { | 107 | { |
108 | struct mm_struct *mm; | 108 | struct mm_struct *mm; |
109 | spu_acquire_saved(ctx); | 109 | |
110 | /* | ||
111 | * This is basically an open-coded spu_acquire_saved, except that | ||
112 | * we don't acquire the state mutex interruptible. | ||
113 | */ | ||
114 | mutex_lock(&ctx->state_mutex); | ||
115 | if (ctx->state != SPU_STATE_SAVED) { | ||
116 | set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); | ||
117 | spu_deactivate(ctx); | ||
118 | } | ||
119 | |||
110 | mm = ctx->owner; | 120 | mm = ctx->owner; |
111 | ctx->owner = NULL; | 121 | ctx->owner = NULL; |
112 | mmput(mm); | 122 | mmput(mm); |
@@ -137,13 +147,20 @@ void spu_unmap_mappings(struct spu_context *ctx) | |||
137 | * spu_acquire_saved - lock spu contex and make sure it is in saved state | 147 | * spu_acquire_saved - lock spu contex and make sure it is in saved state |
138 | * @ctx: spu contex to lock | 148 | * @ctx: spu contex to lock |
139 | */ | 149 | */ |
140 | void spu_acquire_saved(struct spu_context *ctx) | 150 | int spu_acquire_saved(struct spu_context *ctx) |
141 | { | 151 | { |
142 | spu_acquire(ctx); | 152 | int ret; |
153 | |||
154 | ret = spu_acquire(ctx); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
143 | if (ctx->state != SPU_STATE_SAVED) { | 158 | if (ctx->state != SPU_STATE_SAVED) { |
144 | set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); | 159 | set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); |
145 | spu_deactivate(ctx); | 160 | spu_deactivate(ctx); |
146 | } | 161 | } |
162 | |||
163 | return 0; | ||
147 | } | 164 | } |
148 | 165 | ||
149 | /** | 166 | /** |
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index 80f62363e1ce..0c6a96b82b2d 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c | |||
@@ -148,7 +148,9 @@ int spufs_coredump_extra_notes_size(void) | |||
148 | 148 | ||
149 | fd = 0; | 149 | fd = 0; |
150 | while ((ctx = coredump_next_context(&fd)) != NULL) { | 150 | while ((ctx = coredump_next_context(&fd)) != NULL) { |
151 | spu_acquire_saved(ctx); | 151 | rc = spu_acquire_saved(ctx); |
152 | if (rc) | ||
153 | break; | ||
152 | rc = spufs_ctx_note_size(ctx, fd); | 154 | rc = spufs_ctx_note_size(ctx, fd); |
153 | spu_release_saved(ctx); | 155 | spu_release_saved(ctx); |
154 | if (rc < 0) | 156 | if (rc < 0) |
@@ -224,7 +226,9 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) | |||
224 | 226 | ||
225 | fd = 0; | 227 | fd = 0; |
226 | while ((ctx = coredump_next_context(&fd)) != NULL) { | 228 | while ((ctx = coredump_next_context(&fd)) != NULL) { |
227 | spu_acquire_saved(ctx); | 229 | rc = spu_acquire_saved(ctx); |
230 | if (rc) | ||
231 | return rc; | ||
228 | 232 | ||
229 | for (j = 0; spufs_coredump_read[j].name != NULL; j++) { | 233 | for (j = 0; spufs_coredump_read[j].name != NULL; j++) { |
230 | rc = spufs_arch_write_note(ctx, j, file, fd, foffset); | 234 | rc = spufs_arch_write_note(ctx, j, file, fd, foffset); |
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index 720e111f1f6a..825001c2b095 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c | |||
@@ -107,7 +107,7 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
107 | u64 ea, dsisr, access; | 107 | u64 ea, dsisr, access; |
108 | unsigned long flags; | 108 | unsigned long flags; |
109 | unsigned flt = 0; | 109 | unsigned flt = 0; |
110 | int ret; | 110 | int ret, ret2; |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * dar and dsisr get passed from the registers | 113 | * dar and dsisr get passed from the registers |
@@ -146,7 +146,14 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
146 | if (ret) | 146 | if (ret) |
147 | ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt); | 147 | ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt); |
148 | 148 | ||
149 | spu_acquire(ctx); | 149 | /* |
150 | * If spu_acquire fails due to a pending signal we just want to return | ||
151 | * EINTR to userspace even if that means missing the dma restart or | ||
152 | * updating the page fault statistics. | ||
153 | */ | ||
154 | ret2 = spu_acquire(ctx); | ||
155 | if (ret2) | ||
156 | goto out; | ||
150 | 157 | ||
151 | /* | 158 | /* |
152 | * Clear dsisr under ctxt lock after handling the fault, so that | 159 | * Clear dsisr under ctxt lock after handling the fault, so that |
@@ -177,6 +184,7 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
177 | } else | 184 | } else |
178 | spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); | 185 | spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); |
179 | 186 | ||
187 | out: | ||
180 | spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); | 188 | spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); |
181 | return ret; | 189 | return ret; |
182 | } | 190 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 510adc57af90..ba6101ae73a2 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -198,9 +198,12 @@ spufs_mem_read(struct file *file, char __user *buffer, | |||
198 | struct spu_context *ctx = file->private_data; | 198 | struct spu_context *ctx = file->private_data; |
199 | ssize_t ret; | 199 | ssize_t ret; |
200 | 200 | ||
201 | spu_acquire(ctx); | 201 | ret = spu_acquire(ctx); |
202 | if (ret) | ||
203 | return ret; | ||
202 | ret = __spufs_mem_read(ctx, buffer, size, pos); | 204 | ret = __spufs_mem_read(ctx, buffer, size, pos); |
203 | spu_release(ctx); | 205 | spu_release(ctx); |
206 | |||
204 | return ret; | 207 | return ret; |
205 | } | 208 | } |
206 | 209 | ||
@@ -220,7 +223,10 @@ spufs_mem_write(struct file *file, const char __user *buffer, | |||
220 | if (size > LS_SIZE - pos) | 223 | if (size > LS_SIZE - pos) |
221 | size = LS_SIZE - pos; | 224 | size = LS_SIZE - pos; |
222 | 225 | ||
223 | spu_acquire(ctx); | 226 | ret = spu_acquire(ctx); |
227 | if (ret) | ||
228 | return ret; | ||
229 | |||
224 | local_store = ctx->ops->get_ls(ctx); | 230 | local_store = ctx->ops->get_ls(ctx); |
225 | ret = copy_from_user(local_store + pos, buffer, size); | 231 | ret = copy_from_user(local_store + pos, buffer, size); |
226 | spu_release(ctx); | 232 | spu_release(ctx); |
@@ -260,7 +266,8 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, | |||
260 | pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", | 266 | pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", |
261 | addr0, address, offset); | 267 | addr0, address, offset); |
262 | 268 | ||
263 | spu_acquire(ctx); | 269 | if (spu_acquire(ctx)) |
270 | return NOPFN_REFAULT; | ||
264 | 271 | ||
265 | if (ctx->state == SPU_STATE_SAVED) { | 272 | if (ctx->state == SPU_STATE_SAVED) { |
266 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 273 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
@@ -363,20 +370,19 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, | |||
363 | * to return NOPFN_REFAULT because the mappings may have | 370 | * to return NOPFN_REFAULT because the mappings may have |
364 | * hanged. | 371 | * hanged. |
365 | */ | 372 | */ |
366 | spu_acquire(ctx); | 373 | if (spu_acquire(ctx)) |
374 | return NOPFN_REFAULT; | ||
375 | |||
367 | if (ctx->state == SPU_STATE_SAVED) { | 376 | if (ctx->state == SPU_STATE_SAVED) { |
368 | up_read(¤t->mm->mmap_sem); | 377 | up_read(¤t->mm->mmap_sem); |
369 | spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); | 378 | spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); |
370 | down_read(¤t->mm->mmap_sem); | 379 | down_read(¤t->mm->mmap_sem); |
371 | goto out; | 380 | } else { |
381 | area = ctx->spu->problem_phys + ps_offs; | ||
382 | vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); | ||
372 | } | 383 | } |
373 | 384 | ||
374 | area = ctx->spu->problem_phys + ps_offs; | ||
375 | vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); | ||
376 | |||
377 | out: | ||
378 | spu_release(ctx); | 385 | spu_release(ctx); |
379 | |||
380 | return NOPFN_REFAULT; | 386 | return NOPFN_REFAULT; |
381 | } | 387 | } |
382 | 388 | ||
@@ -413,8 +419,11 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) | |||
413 | static int spufs_cntl_get(void *data, u64 *val) | 419 | static int spufs_cntl_get(void *data, u64 *val) |
414 | { | 420 | { |
415 | struct spu_context *ctx = data; | 421 | struct spu_context *ctx = data; |
422 | int ret; | ||
416 | 423 | ||
417 | spu_acquire(ctx); | 424 | ret = spu_acquire(ctx); |
425 | if (ret) | ||
426 | return ret; | ||
418 | *val = ctx->ops->status_read(ctx); | 427 | *val = ctx->ops->status_read(ctx); |
419 | spu_release(ctx); | 428 | spu_release(ctx); |
420 | 429 | ||
@@ -424,8 +433,11 @@ static int spufs_cntl_get(void *data, u64 *val) | |||
424 | static int spufs_cntl_set(void *data, u64 val) | 433 | static int spufs_cntl_set(void *data, u64 val) |
425 | { | 434 | { |
426 | struct spu_context *ctx = data; | 435 | struct spu_context *ctx = data; |
436 | int ret; | ||
427 | 437 | ||
428 | spu_acquire(ctx); | 438 | ret = spu_acquire(ctx); |
439 | if (ret) | ||
440 | return ret; | ||
429 | ctx->ops->runcntl_write(ctx, val); | 441 | ctx->ops->runcntl_write(ctx, val); |
430 | spu_release(ctx); | 442 | spu_release(ctx); |
431 | 443 | ||
@@ -493,7 +505,9 @@ spufs_regs_read(struct file *file, char __user *buffer, | |||
493 | int ret; | 505 | int ret; |
494 | struct spu_context *ctx = file->private_data; | 506 | struct spu_context *ctx = file->private_data; |
495 | 507 | ||
496 | spu_acquire_saved(ctx); | 508 | ret = spu_acquire_saved(ctx); |
509 | if (ret) | ||
510 | return ret; | ||
497 | ret = __spufs_regs_read(ctx, buffer, size, pos); | 511 | ret = __spufs_regs_read(ctx, buffer, size, pos); |
498 | spu_release_saved(ctx); | 512 | spu_release_saved(ctx); |
499 | return ret; | 513 | return ret; |
@@ -512,7 +526,9 @@ spufs_regs_write(struct file *file, const char __user *buffer, | |||
512 | return -EFBIG; | 526 | return -EFBIG; |
513 | *pos += size; | 527 | *pos += size; |
514 | 528 | ||
515 | spu_acquire_saved(ctx); | 529 | ret = spu_acquire_saved(ctx); |
530 | if (ret) | ||
531 | return ret; | ||
516 | 532 | ||
517 | ret = copy_from_user(lscsa->gprs + *pos - size, | 533 | ret = copy_from_user(lscsa->gprs + *pos - size, |
518 | buffer, size) ? -EFAULT : size; | 534 | buffer, size) ? -EFAULT : size; |
@@ -544,7 +560,9 @@ spufs_fpcr_read(struct file *file, char __user * buffer, | |||
544 | int ret; | 560 | int ret; |
545 | struct spu_context *ctx = file->private_data; | 561 | struct spu_context *ctx = file->private_data; |
546 | 562 | ||
547 | spu_acquire_saved(ctx); | 563 | ret = spu_acquire_saved(ctx); |
564 | if (ret) | ||
565 | return ret; | ||
548 | ret = __spufs_fpcr_read(ctx, buffer, size, pos); | 566 | ret = __spufs_fpcr_read(ctx, buffer, size, pos); |
549 | spu_release_saved(ctx); | 567 | spu_release_saved(ctx); |
550 | return ret; | 568 | return ret; |
@@ -561,10 +579,12 @@ spufs_fpcr_write(struct file *file, const char __user * buffer, | |||
561 | size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); | 579 | size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); |
562 | if (size <= 0) | 580 | if (size <= 0) |
563 | return -EFBIG; | 581 | return -EFBIG; |
564 | *pos += size; | ||
565 | 582 | ||
566 | spu_acquire_saved(ctx); | 583 | ret = spu_acquire_saved(ctx); |
584 | if (ret) | ||
585 | return ret; | ||
567 | 586 | ||
587 | *pos += size; | ||
568 | ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, | 588 | ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, |
569 | buffer, size) ? -EFAULT : size; | 589 | buffer, size) ? -EFAULT : size; |
570 | 590 | ||
@@ -611,7 +631,10 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf, | |||
611 | 631 | ||
612 | udata = (void __user *)buf; | 632 | udata = (void __user *)buf; |
613 | 633 | ||
614 | spu_acquire(ctx); | 634 | count = spu_acquire(ctx); |
635 | if (count) | ||
636 | return count; | ||
637 | |||
615 | for (count = 0; (count + 4) <= len; count += 4, udata++) { | 638 | for (count = 0; (count + 4) <= len; count += 4, udata++) { |
616 | int ret; | 639 | int ret; |
617 | ret = ctx->ops->mbox_read(ctx, &mbox_data); | 640 | ret = ctx->ops->mbox_read(ctx, &mbox_data); |
@@ -647,12 +670,15 @@ static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf, | |||
647 | size_t len, loff_t *pos) | 670 | size_t len, loff_t *pos) |
648 | { | 671 | { |
649 | struct spu_context *ctx = file->private_data; | 672 | struct spu_context *ctx = file->private_data; |
673 | ssize_t ret; | ||
650 | u32 mbox_stat; | 674 | u32 mbox_stat; |
651 | 675 | ||
652 | if (len < 4) | 676 | if (len < 4) |
653 | return -EINVAL; | 677 | return -EINVAL; |
654 | 678 | ||
655 | spu_acquire(ctx); | 679 | ret = spu_acquire(ctx); |
680 | if (ret) | ||
681 | return ret; | ||
656 | 682 | ||
657 | mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; | 683 | mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; |
658 | 684 | ||
@@ -721,7 +747,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf, | |||
721 | 747 | ||
722 | udata = (void __user *)buf; | 748 | udata = (void __user *)buf; |
723 | 749 | ||
724 | spu_acquire(ctx); | 750 | count = spu_acquire(ctx); |
751 | if (count) | ||
752 | return count; | ||
725 | 753 | ||
726 | /* wait only for the first element */ | 754 | /* wait only for the first element */ |
727 | count = 0; | 755 | count = 0; |
@@ -767,7 +795,11 @@ static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) | |||
767 | 795 | ||
768 | poll_wait(file, &ctx->ibox_wq, wait); | 796 | poll_wait(file, &ctx->ibox_wq, wait); |
769 | 797 | ||
770 | spu_acquire(ctx); | 798 | /* |
799 | * For now keep this uninterruptible and also ignore the rule | ||
800 | * that poll should not sleep. Will be fixed later. | ||
801 | */ | ||
802 | mutex_lock(&ctx->state_mutex); | ||
771 | mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); | 803 | mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); |
772 | spu_release(ctx); | 804 | spu_release(ctx); |
773 | 805 | ||
@@ -785,12 +817,15 @@ static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, | |||
785 | size_t len, loff_t *pos) | 817 | size_t len, loff_t *pos) |
786 | { | 818 | { |
787 | struct spu_context *ctx = file->private_data; | 819 | struct spu_context *ctx = file->private_data; |
820 | ssize_t ret; | ||
788 | u32 ibox_stat; | 821 | u32 ibox_stat; |
789 | 822 | ||
790 | if (len < 4) | 823 | if (len < 4) |
791 | return -EINVAL; | 824 | return -EINVAL; |
792 | 825 | ||
793 | spu_acquire(ctx); | 826 | ret = spu_acquire(ctx); |
827 | if (ret) | ||
828 | return ret; | ||
794 | ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; | 829 | ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; |
795 | spu_release(ctx); | 830 | spu_release(ctx); |
796 | 831 | ||
@@ -862,7 +897,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, | |||
862 | if (__get_user(wbox_data, udata)) | 897 | if (__get_user(wbox_data, udata)) |
863 | return -EFAULT; | 898 | return -EFAULT; |
864 | 899 | ||
865 | spu_acquire(ctx); | 900 | count = spu_acquire(ctx); |
901 | if (count) | ||
902 | return count; | ||
866 | 903 | ||
867 | /* | 904 | /* |
868 | * make sure we can at least write one element, by waiting | 905 | * make sure we can at least write one element, by waiting |
@@ -903,7 +940,11 @@ static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) | |||
903 | 940 | ||
904 | poll_wait(file, &ctx->wbox_wq, wait); | 941 | poll_wait(file, &ctx->wbox_wq, wait); |
905 | 942 | ||
906 | spu_acquire(ctx); | 943 | /* |
944 | * For now keep this uninterruptible and also ignore the rule | ||
945 | * that poll should not sleep. Will be fixed later. | ||
946 | */ | ||
947 | mutex_lock(&ctx->state_mutex); | ||
907 | mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); | 948 | mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); |
908 | spu_release(ctx); | 949 | spu_release(ctx); |
909 | 950 | ||
@@ -921,12 +962,15 @@ static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, | |||
921 | size_t len, loff_t *pos) | 962 | size_t len, loff_t *pos) |
922 | { | 963 | { |
923 | struct spu_context *ctx = file->private_data; | 964 | struct spu_context *ctx = file->private_data; |
965 | ssize_t ret; | ||
924 | u32 wbox_stat; | 966 | u32 wbox_stat; |
925 | 967 | ||
926 | if (len < 4) | 968 | if (len < 4) |
927 | return -EINVAL; | 969 | return -EINVAL; |
928 | 970 | ||
929 | spu_acquire(ctx); | 971 | ret = spu_acquire(ctx); |
972 | if (ret) | ||
973 | return ret; | ||
930 | wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; | 974 | wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; |
931 | spu_release(ctx); | 975 | spu_release(ctx); |
932 | 976 | ||
@@ -997,7 +1041,9 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, | |||
997 | int ret; | 1041 | int ret; |
998 | struct spu_context *ctx = file->private_data; | 1042 | struct spu_context *ctx = file->private_data; |
999 | 1043 | ||
1000 | spu_acquire_saved(ctx); | 1044 | ret = spu_acquire_saved(ctx); |
1045 | if (ret) | ||
1046 | return ret; | ||
1001 | ret = __spufs_signal1_read(ctx, buf, len, pos); | 1047 | ret = __spufs_signal1_read(ctx, buf, len, pos); |
1002 | spu_release_saved(ctx); | 1048 | spu_release_saved(ctx); |
1003 | 1049 | ||
@@ -1008,6 +1054,7 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, | |||
1008 | size_t len, loff_t *pos) | 1054 | size_t len, loff_t *pos) |
1009 | { | 1055 | { |
1010 | struct spu_context *ctx; | 1056 | struct spu_context *ctx; |
1057 | ssize_t ret; | ||
1011 | u32 data; | 1058 | u32 data; |
1012 | 1059 | ||
1013 | ctx = file->private_data; | 1060 | ctx = file->private_data; |
@@ -1018,7 +1065,9 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, | |||
1018 | if (copy_from_user(&data, buf, 4)) | 1065 | if (copy_from_user(&data, buf, 4)) |
1019 | return -EFAULT; | 1066 | return -EFAULT; |
1020 | 1067 | ||
1021 | spu_acquire(ctx); | 1068 | ret = spu_acquire(ctx); |
1069 | if (ret) | ||
1070 | return ret; | ||
1022 | ctx->ops->signal1_write(ctx, data); | 1071 | ctx->ops->signal1_write(ctx, data); |
1023 | spu_release(ctx); | 1072 | spu_release(ctx); |
1024 | 1073 | ||
@@ -1128,7 +1177,9 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf, | |||
1128 | struct spu_context *ctx = file->private_data; | 1177 | struct spu_context *ctx = file->private_data; |
1129 | int ret; | 1178 | int ret; |
1130 | 1179 | ||
1131 | spu_acquire_saved(ctx); | 1180 | ret = spu_acquire_saved(ctx); |
1181 | if (ret) | ||
1182 | return ret; | ||
1132 | ret = __spufs_signal2_read(ctx, buf, len, pos); | 1183 | ret = __spufs_signal2_read(ctx, buf, len, pos); |
1133 | spu_release_saved(ctx); | 1184 | spu_release_saved(ctx); |
1134 | 1185 | ||
@@ -1139,6 +1190,7 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, | |||
1139 | size_t len, loff_t *pos) | 1190 | size_t len, loff_t *pos) |
1140 | { | 1191 | { |
1141 | struct spu_context *ctx; | 1192 | struct spu_context *ctx; |
1193 | ssize_t ret; | ||
1142 | u32 data; | 1194 | u32 data; |
1143 | 1195 | ||
1144 | ctx = file->private_data; | 1196 | ctx = file->private_data; |
@@ -1149,7 +1201,9 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, | |||
1149 | if (copy_from_user(&data, buf, 4)) | 1201 | if (copy_from_user(&data, buf, 4)) |
1150 | return -EFAULT; | 1202 | return -EFAULT; |
1151 | 1203 | ||
1152 | spu_acquire(ctx); | 1204 | ret = spu_acquire(ctx); |
1205 | if (ret) | ||
1206 | return ret; | ||
1153 | ctx->ops->signal2_write(ctx, data); | 1207 | ctx->ops->signal2_write(ctx, data); |
1154 | spu_release(ctx); | 1208 | spu_release(ctx); |
1155 | 1209 | ||
@@ -1220,13 +1274,18 @@ static const struct file_operations spufs_signal2_nosched_fops = { | |||
1220 | static int __##__get(void *data, u64 *val) \ | 1274 | static int __##__get(void *data, u64 *val) \ |
1221 | { \ | 1275 | { \ |
1222 | struct spu_context *ctx = data; \ | 1276 | struct spu_context *ctx = data; \ |
1277 | int ret = 0; \ | ||
1223 | \ | 1278 | \ |
1224 | if (__acquire == SPU_ATTR_ACQUIRE) { \ | 1279 | if (__acquire == SPU_ATTR_ACQUIRE) { \ |
1225 | spu_acquire(ctx); \ | 1280 | ret = spu_acquire(ctx); \ |
1281 | if (ret) \ | ||
1282 | return ret; \ | ||
1226 | *val = __get(ctx); \ | 1283 | *val = __get(ctx); \ |
1227 | spu_release(ctx); \ | 1284 | spu_release(ctx); \ |
1228 | } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \ | 1285 | } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \ |
1229 | spu_acquire_saved(ctx); \ | 1286 | ret = spu_acquire_saved(ctx); \ |
1287 | if (ret) \ | ||
1288 | return ret; \ | ||
1230 | *val = __get(ctx); \ | 1289 | *val = __get(ctx); \ |
1231 | spu_release_saved(ctx); \ | 1290 | spu_release_saved(ctx); \ |
1232 | } else \ | 1291 | } else \ |
@@ -1239,8 +1298,11 @@ DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt); | |||
1239 | static int spufs_signal1_type_set(void *data, u64 val) | 1298 | static int spufs_signal1_type_set(void *data, u64 val) |
1240 | { | 1299 | { |
1241 | struct spu_context *ctx = data; | 1300 | struct spu_context *ctx = data; |
1301 | int ret; | ||
1242 | 1302 | ||
1243 | spu_acquire(ctx); | 1303 | ret = spu_acquire(ctx); |
1304 | if (ret) | ||
1305 | return ret; | ||
1244 | ctx->ops->signal1_type_set(ctx, val); | 1306 | ctx->ops->signal1_type_set(ctx, val); |
1245 | spu_release(ctx); | 1307 | spu_release(ctx); |
1246 | 1308 | ||
@@ -1258,8 +1320,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get, | |||
1258 | static int spufs_signal2_type_set(void *data, u64 val) | 1320 | static int spufs_signal2_type_set(void *data, u64 val) |
1259 | { | 1321 | { |
1260 | struct spu_context *ctx = data; | 1322 | struct spu_context *ctx = data; |
1323 | int ret; | ||
1261 | 1324 | ||
1262 | spu_acquire(ctx); | 1325 | ret = spu_acquire(ctx); |
1326 | if (ret) | ||
1327 | return ret; | ||
1263 | ctx->ops->signal2_type_set(ctx, val); | 1328 | ctx->ops->signal2_type_set(ctx, val); |
1264 | spu_release(ctx); | 1329 | spu_release(ctx); |
1265 | 1330 | ||
@@ -1512,12 +1577,17 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer, | |||
1512 | if (size != 4) | 1577 | if (size != 4) |
1513 | goto out; | 1578 | goto out; |
1514 | 1579 | ||
1515 | spu_acquire(ctx); | 1580 | ret = spu_acquire(ctx); |
1581 | if (ret) | ||
1582 | return ret; | ||
1583 | |||
1584 | ret = -EINVAL; | ||
1516 | if (file->f_flags & O_NONBLOCK) { | 1585 | if (file->f_flags & O_NONBLOCK) { |
1517 | status = ctx->ops->read_mfc_tagstatus(ctx); | 1586 | status = ctx->ops->read_mfc_tagstatus(ctx); |
1518 | if (!(status & ctx->tagwait)) | 1587 | if (!(status & ctx->tagwait)) |
1519 | ret = -EAGAIN; | 1588 | ret = -EAGAIN; |
1520 | else | 1589 | else |
1590 | /* XXX(hch): shouldn't we clear ret here? */ | ||
1521 | ctx->tagwait &= ~status; | 1591 | ctx->tagwait &= ~status; |
1522 | } else { | 1592 | } else { |
1523 | ret = spufs_wait(ctx->mfc_wq, | 1593 | ret = spufs_wait(ctx->mfc_wq, |
@@ -1642,7 +1712,10 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, | |||
1642 | if (ret) | 1712 | if (ret) |
1643 | goto out; | 1713 | goto out; |
1644 | 1714 | ||
1645 | spu_acquire(ctx); | 1715 | ret = spu_acquire(ctx); |
1716 | if (ret) | ||
1717 | goto out; | ||
1718 | |||
1646 | ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); | 1719 | ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); |
1647 | if (ret) | 1720 | if (ret) |
1648 | goto out; | 1721 | goto out; |
@@ -1677,7 +1750,11 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) | |||
1677 | 1750 | ||
1678 | poll_wait(file, &ctx->mfc_wq, wait); | 1751 | poll_wait(file, &ctx->mfc_wq, wait); |
1679 | 1752 | ||
1680 | spu_acquire(ctx); | 1753 | /* |
1754 | * For now keep this uninterruptible and also ignore the rule | ||
1755 | * that poll should not sleep. Will be fixed later. | ||
1756 | */ | ||
1757 | mutex_lock(&ctx->state_mutex); | ||
1681 | ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); | 1758 | ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); |
1682 | free_elements = ctx->ops->get_mfc_free_elements(ctx); | 1759 | free_elements = ctx->ops->get_mfc_free_elements(ctx); |
1683 | tagstatus = ctx->ops->read_mfc_tagstatus(ctx); | 1760 | tagstatus = ctx->ops->read_mfc_tagstatus(ctx); |
@@ -1700,7 +1777,9 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id) | |||
1700 | struct spu_context *ctx = file->private_data; | 1777 | struct spu_context *ctx = file->private_data; |
1701 | int ret; | 1778 | int ret; |
1702 | 1779 | ||
1703 | spu_acquire(ctx); | 1780 | ret = spu_acquire(ctx); |
1781 | if (ret) | ||
1782 | return ret; | ||
1704 | #if 0 | 1783 | #if 0 |
1705 | /* this currently hangs */ | 1784 | /* this currently hangs */ |
1706 | ret = spufs_wait(ctx->mfc_wq, | 1785 | ret = spufs_wait(ctx->mfc_wq, |
@@ -1746,7 +1825,11 @@ static const struct file_operations spufs_mfc_fops = { | |||
1746 | static int spufs_npc_set(void *data, u64 val) | 1825 | static int spufs_npc_set(void *data, u64 val) |
1747 | { | 1826 | { |
1748 | struct spu_context *ctx = data; | 1827 | struct spu_context *ctx = data; |
1749 | spu_acquire(ctx); | 1828 | int ret; |
1829 | |||
1830 | ret = spu_acquire(ctx); | ||
1831 | if (ret) | ||
1832 | return ret; | ||
1750 | ctx->ops->npc_write(ctx, val); | 1833 | ctx->ops->npc_write(ctx, val); |
1751 | spu_release(ctx); | 1834 | spu_release(ctx); |
1752 | 1835 | ||
@@ -1764,7 +1847,11 @@ static int spufs_decr_set(void *data, u64 val) | |||
1764 | { | 1847 | { |
1765 | struct spu_context *ctx = data; | 1848 | struct spu_context *ctx = data; |
1766 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1849 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1767 | spu_acquire_saved(ctx); | 1850 | int ret; |
1851 | |||
1852 | ret = spu_acquire_saved(ctx); | ||
1853 | if (ret) | ||
1854 | return ret; | ||
1768 | lscsa->decr.slot[0] = (u32) val; | 1855 | lscsa->decr.slot[0] = (u32) val; |
1769 | spu_release_saved(ctx); | 1856 | spu_release_saved(ctx); |
1770 | 1857 | ||
@@ -1782,7 +1869,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, | |||
1782 | static int spufs_decr_status_set(void *data, u64 val) | 1869 | static int spufs_decr_status_set(void *data, u64 val) |
1783 | { | 1870 | { |
1784 | struct spu_context *ctx = data; | 1871 | struct spu_context *ctx = data; |
1785 | spu_acquire_saved(ctx); | 1872 | int ret; |
1873 | |||
1874 | ret = spu_acquire_saved(ctx); | ||
1875 | if (ret) | ||
1876 | return ret; | ||
1786 | if (val) | 1877 | if (val) |
1787 | ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; | 1878 | ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; |
1788 | else | 1879 | else |
@@ -1807,7 +1898,11 @@ static int spufs_event_mask_set(void *data, u64 val) | |||
1807 | { | 1898 | { |
1808 | struct spu_context *ctx = data; | 1899 | struct spu_context *ctx = data; |
1809 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1900 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1810 | spu_acquire_saved(ctx); | 1901 | int ret; |
1902 | |||
1903 | ret = spu_acquire_saved(ctx); | ||
1904 | if (ret) | ||
1905 | return ret; | ||
1811 | lscsa->event_mask.slot[0] = (u32) val; | 1906 | lscsa->event_mask.slot[0] = (u32) val; |
1812 | spu_release_saved(ctx); | 1907 | spu_release_saved(ctx); |
1813 | 1908 | ||
@@ -1840,7 +1935,11 @@ static int spufs_srr0_set(void *data, u64 val) | |||
1840 | { | 1935 | { |
1841 | struct spu_context *ctx = data; | 1936 | struct spu_context *ctx = data; |
1842 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1937 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1843 | spu_acquire_saved(ctx); | 1938 | int ret; |
1939 | |||
1940 | ret = spu_acquire_saved(ctx); | ||
1941 | if (ret) | ||
1942 | return ret; | ||
1844 | lscsa->srr0.slot[0] = (u32) val; | 1943 | lscsa->srr0.slot[0] = (u32) val; |
1845 | spu_release_saved(ctx); | 1944 | spu_release_saved(ctx); |
1846 | 1945 | ||
@@ -1947,7 +2046,9 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, | |||
1947 | if (!access_ok(VERIFY_WRITE, buf, len)) | 2046 | if (!access_ok(VERIFY_WRITE, buf, len)) |
1948 | return -EFAULT; | 2047 | return -EFAULT; |
1949 | 2048 | ||
1950 | spu_acquire_saved(ctx); | 2049 | ret = spu_acquire_saved(ctx); |
2050 | if (ret) | ||
2051 | return ret; | ||
1951 | spin_lock(&ctx->csa.register_lock); | 2052 | spin_lock(&ctx->csa.register_lock); |
1952 | ret = __spufs_mbox_info_read(ctx, buf, len, pos); | 2053 | ret = __spufs_mbox_info_read(ctx, buf, len, pos); |
1953 | spin_unlock(&ctx->csa.register_lock); | 2054 | spin_unlock(&ctx->csa.register_lock); |
@@ -1985,7 +2086,9 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, | |||
1985 | if (!access_ok(VERIFY_WRITE, buf, len)) | 2086 | if (!access_ok(VERIFY_WRITE, buf, len)) |
1986 | return -EFAULT; | 2087 | return -EFAULT; |
1987 | 2088 | ||
1988 | spu_acquire_saved(ctx); | 2089 | ret = spu_acquire_saved(ctx); |
2090 | if (ret) | ||
2091 | return ret; | ||
1989 | spin_lock(&ctx->csa.register_lock); | 2092 | spin_lock(&ctx->csa.register_lock); |
1990 | ret = __spufs_ibox_info_read(ctx, buf, len, pos); | 2093 | ret = __spufs_ibox_info_read(ctx, buf, len, pos); |
1991 | spin_unlock(&ctx->csa.register_lock); | 2094 | spin_unlock(&ctx->csa.register_lock); |
@@ -2026,7 +2129,9 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, | |||
2026 | if (!access_ok(VERIFY_WRITE, buf, len)) | 2129 | if (!access_ok(VERIFY_WRITE, buf, len)) |
2027 | return -EFAULT; | 2130 | return -EFAULT; |
2028 | 2131 | ||
2029 | spu_acquire_saved(ctx); | 2132 | ret = spu_acquire_saved(ctx); |
2133 | if (ret) | ||
2134 | return ret; | ||
2030 | spin_lock(&ctx->csa.register_lock); | 2135 | spin_lock(&ctx->csa.register_lock); |
2031 | ret = __spufs_wbox_info_read(ctx, buf, len, pos); | 2136 | ret = __spufs_wbox_info_read(ctx, buf, len, pos); |
2032 | spin_unlock(&ctx->csa.register_lock); | 2137 | spin_unlock(&ctx->csa.register_lock); |
@@ -2076,7 +2181,9 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, | |||
2076 | if (!access_ok(VERIFY_WRITE, buf, len)) | 2181 | if (!access_ok(VERIFY_WRITE, buf, len)) |
2077 | return -EFAULT; | 2182 | return -EFAULT; |
2078 | 2183 | ||
2079 | spu_acquire_saved(ctx); | 2184 | ret = spu_acquire_saved(ctx); |
2185 | if (ret) | ||
2186 | return ret; | ||
2080 | spin_lock(&ctx->csa.register_lock); | 2187 | spin_lock(&ctx->csa.register_lock); |
2081 | ret = __spufs_dma_info_read(ctx, buf, len, pos); | 2188 | ret = __spufs_dma_info_read(ctx, buf, len, pos); |
2082 | spin_unlock(&ctx->csa.register_lock); | 2189 | spin_unlock(&ctx->csa.register_lock); |
@@ -2127,7 +2234,9 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, | |||
2127 | struct spu_context *ctx = file->private_data; | 2234 | struct spu_context *ctx = file->private_data; |
2128 | int ret; | 2235 | int ret; |
2129 | 2236 | ||
2130 | spu_acquire_saved(ctx); | 2237 | ret = spu_acquire_saved(ctx); |
2238 | if (ret) | ||
2239 | return ret; | ||
2131 | spin_lock(&ctx->csa.register_lock); | 2240 | spin_lock(&ctx->csa.register_lock); |
2132 | ret = __spufs_proxydma_info_read(ctx, buf, len, pos); | 2241 | ret = __spufs_proxydma_info_read(ctx, buf, len, pos); |
2133 | spin_unlock(&ctx->csa.register_lock); | 2242 | spin_unlock(&ctx->csa.register_lock); |
@@ -2216,8 +2325,12 @@ static unsigned long long spufs_class2_intrs(struct spu_context *ctx) | |||
2216 | static int spufs_show_stat(struct seq_file *s, void *private) | 2325 | static int spufs_show_stat(struct seq_file *s, void *private) |
2217 | { | 2326 | { |
2218 | struct spu_context *ctx = s->private; | 2327 | struct spu_context *ctx = s->private; |
2328 | int ret; | ||
2329 | |||
2330 | ret = spu_acquire(ctx); | ||
2331 | if (ret) | ||
2332 | return ret; | ||
2219 | 2333 | ||
2220 | spu_acquire(ctx); | ||
2221 | seq_printf(s, "%s %llu %llu %llu %llu " | 2334 | seq_printf(s, "%s %llu %llu %llu %llu " |
2222 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", | 2335 | "%llu %llu %llu %llu %llu %llu %llu %llu\n", |
2223 | ctx_state_names[ctx->stats.util_state], | 2336 | ctx_state_names[ctx->stats.util_state], |
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index b380050cdbc7..c01a09da1e56 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c | |||
@@ -292,7 +292,7 @@ static int spu_process_callback(struct spu_context *ctx) | |||
292 | u32 ls_pointer, npc; | 292 | u32 ls_pointer, npc; |
293 | void __iomem *ls; | 293 | void __iomem *ls; |
294 | long spu_ret; | 294 | long spu_ret; |
295 | int ret; | 295 | int ret, ret2; |
296 | 296 | ||
297 | /* get syscall block from local store */ | 297 | /* get syscall block from local store */ |
298 | npc = ctx->ops->npc_read(ctx) & ~3; | 298 | npc = ctx->ops->npc_read(ctx) & ~3; |
@@ -314,9 +314,11 @@ static int spu_process_callback(struct spu_context *ctx) | |||
314 | if (spu_ret <= -ERESTARTSYS) { | 314 | if (spu_ret <= -ERESTARTSYS) { |
315 | ret = spu_handle_restartsys(ctx, &spu_ret, &npc); | 315 | ret = spu_handle_restartsys(ctx, &spu_ret, &npc); |
316 | } | 316 | } |
317 | spu_acquire(ctx); | 317 | ret2 = spu_acquire(ctx); |
318 | if (ret == -ERESTARTSYS) | 318 | if (ret == -ERESTARTSYS) |
319 | return ret; | 319 | return ret; |
320 | if (ret2) | ||
321 | return -EINTR; | ||
320 | } | 322 | } |
321 | 323 | ||
322 | /* write result, jump over indirect pointer */ | 324 | /* write result, jump over indirect pointer */ |
@@ -338,7 +340,9 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) | |||
338 | spu_enable_spu(ctx); | 340 | spu_enable_spu(ctx); |
339 | ctx->event_return = 0; | 341 | ctx->event_return = 0; |
340 | 342 | ||
341 | spu_acquire(ctx); | 343 | ret = spu_acquire(ctx); |
344 | if (ret) | ||
345 | goto out_unlock; | ||
342 | 346 | ||
343 | spu_update_sched_info(ctx); | 347 | spu_update_sched_info(ctx); |
344 | 348 | ||
@@ -414,6 +418,7 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) | |||
414 | 418 | ||
415 | out: | 419 | out: |
416 | *event = ctx->event_return; | 420 | *event = ctx->event_return; |
421 | out_unlock: | ||
417 | mutex_unlock(&ctx->run_mutex); | 422 | mutex_unlock(&ctx->run_mutex); |
418 | return ret; | 423 | return ret; |
419 | } | 424 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 2775c1652ba4..eee7cef28f1a 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
@@ -705,7 +705,9 @@ static void __spu_schedule(struct spu *spu, struct spu_context *ctx) | |||
705 | 705 | ||
706 | static void spu_schedule(struct spu *spu, struct spu_context *ctx) | 706 | static void spu_schedule(struct spu *spu, struct spu_context *ctx) |
707 | { | 707 | { |
708 | spu_acquire(ctx); | 708 | /* not a candidate for interruptible because it's called either |
709 | from the scheduler thread or from spu_deactivate */ | ||
710 | mutex_lock(&ctx->state_mutex); | ||
709 | __spu_schedule(spu, ctx); | 711 | __spu_schedule(spu, ctx); |
710 | spu_release(ctx); | 712 | spu_release(ctx); |
711 | } | 713 | } |
@@ -823,7 +825,9 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio) | |||
823 | else { | 825 | else { |
824 | spu_release(ctx); | 826 | spu_release(ctx); |
825 | spu_schedule(spu, new); | 827 | spu_schedule(spu, new); |
826 | spu_acquire(ctx); | 828 | /* this one can't easily be made |
829 | interruptible */ | ||
830 | mutex_lock(&ctx->state_mutex); | ||
827 | } | 831 | } |
828 | } | 832 | } |
829 | } | 833 | } |
@@ -867,7 +871,8 @@ static noinline void spusched_tick(struct spu_context *ctx) | |||
867 | struct spu *spu = NULL; | 871 | struct spu *spu = NULL; |
868 | u32 status; | 872 | u32 status; |
869 | 873 | ||
870 | spu_acquire(ctx); | 874 | if (spu_acquire(ctx)) |
875 | BUG(); /* a kernel thread never has signals pending */ | ||
871 | 876 | ||
872 | if (ctx->state != SPU_STATE_RUNNABLE) | 877 | if (ctx->state != SPU_STATE_RUNNABLE) |
873 | goto out; | 878 | goto out; |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 412de58f5b0f..0e114038ea6f 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -229,9 +229,9 @@ struct spu *affinity_check(struct spu_context *ctx); | |||
229 | 229 | ||
230 | /* context management */ | 230 | /* context management */ |
231 | extern atomic_t nr_spu_contexts; | 231 | extern atomic_t nr_spu_contexts; |
232 | static inline void spu_acquire(struct spu_context *ctx) | 232 | static inline int __must_check spu_acquire(struct spu_context *ctx) |
233 | { | 233 | { |
234 | mutex_lock(&ctx->state_mutex); | 234 | return mutex_lock_interruptible(&ctx->state_mutex); |
235 | } | 235 | } |
236 | 236 | ||
237 | static inline void spu_release(struct spu_context *ctx) | 237 | static inline void spu_release(struct spu_context *ctx) |
@@ -246,7 +246,7 @@ int put_spu_context(struct spu_context *ctx); | |||
246 | void spu_unmap_mappings(struct spu_context *ctx); | 246 | void spu_unmap_mappings(struct spu_context *ctx); |
247 | 247 | ||
248 | void spu_forget(struct spu_context *ctx); | 248 | void spu_forget(struct spu_context *ctx); |
249 | void spu_acquire_saved(struct spu_context *ctx); | 249 | int __must_check spu_acquire_saved(struct spu_context *ctx); |
250 | void spu_release_saved(struct spu_context *ctx); | 250 | void spu_release_saved(struct spu_context *ctx); |
251 | 251 | ||
252 | int spu_stopped(struct spu_context *ctx, u32 * stat); | 252 | int spu_stopped(struct spu_context *ctx, u32 * stat); |
@@ -284,7 +284,9 @@ extern char *isolated_loader; | |||
284 | } \ | 284 | } \ |
285 | spu_release(ctx); \ | 285 | spu_release(ctx); \ |
286 | schedule(); \ | 286 | schedule(); \ |
287 | spu_acquire(ctx); \ | 287 | __ret = spu_acquire(ctx); \ |
288 | if (__ret) \ | ||
289 | break; \ | ||
288 | } \ | 290 | } \ |
289 | finish_wait(&(wq), &__wait); \ | 291 | finish_wait(&(wq), &__wait); \ |
290 | __ret; \ | 292 | __ret; \ |