aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index c66c3756970d..f7a7e8635fb6 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -367,6 +367,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
367 return NOPFN_SIGBUS; 367 return NOPFN_SIGBUS;
368 368
369 /* 369 /*
370 * Because we release the mmap_sem, the context may be destroyed while
371 * we're in spu_wait. Grab an extra reference so it isn't destroyed
372 * in the meantime.
373 */
374 get_spu_context(ctx);
375
376 /*
370 * We have to wait for context to be loaded before we have 377 * We have to wait for context to be loaded before we have
371 * pages to hand out to the user, but we don't want to wait 378 * pages to hand out to the user, but we don't want to wait
372 * with the mmap_sem held. 379 * with the mmap_sem held.
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 * hanged. 382 * hanged.
376 */ 383 */
377 if (spu_acquire(ctx)) 384 if (spu_acquire(ctx))
378 return NOPFN_REFAULT; 385 goto refault;
379 386
380 if (ctx->state == SPU_STATE_SAVED) { 387 if (ctx->state == SPU_STATE_SAVED) {
381 up_read(&current->mm->mmap_sem); 388 up_read(&current->mm->mmap_sem);
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
391 398
392 if (!ret) 399 if (!ret)
393 spu_release(ctx); 400 spu_release(ctx);
401
402refault:
403 put_spu_context(ctx);
394 return NOPFN_REFAULT; 404 return NOPFN_REFAULT;
395} 405}
396 406