|
@@ -358,6 +358,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|
|
{
|
|
|
struct spu_context *ctx = vma->vm_file->private_data;
|
|
|
unsigned long area, offset = address - vma->vm_start;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);
|
|
|
|
|
@@ -379,7 +380,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|
|
if (ctx->state == SPU_STATE_SAVED) {
|
|
|
up_read(¤t->mm->mmap_sem);
|
|
|
spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
|
|
|
- spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
|
|
|
+ ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
|
|
|
spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
|
|
|
down_read(¤t->mm->mmap_sem);
|
|
|
} else {
|
|
@@ -388,7 +389,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|
|
spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
|
|
|
}
|
|
|
|
|
|
- spu_release(ctx);
|
|
|
+ if (!ret)
|
|
|
+ spu_release(ctx);
|
|
|
return NOPFN_REFAULT;
|
|
|
}
|
|
|
|
|
@@ -755,23 +757,25 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
|
|
|
|
|
|
count = spu_acquire(ctx);
|
|
|
if (count)
|
|
|
- return count;
|
|
|
+ goto out;
|
|
|
|
|
|
/* wait only for the first element */
|
|
|
count = 0;
|
|
|
if (file->f_flags & O_NONBLOCK) {
|
|
|
- if (!spu_ibox_read(ctx, &ibox_data))
|
|
|
+ if (!spu_ibox_read(ctx, &ibox_data)) {
|
|
|
count = -EAGAIN;
|
|
|
+ goto out_unlock;
|
|
|
+ }
|
|
|
} else {
|
|
|
count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
|
|
|
+ if (count)
|
|
|
+ goto out;
|
|
|
}
|
|
|
- if (count)
|
|
|
- goto out;
|
|
|
|
|
|
/* if we can't write at all, return -EFAULT */
|
|
|
count = __put_user(ibox_data, udata);
|
|
|
if (count)
|
|
|
- goto out;
|
|
|
+ goto out_unlock;
|
|
|
|
|
|
for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
|
|
|
int ret;
|
|
@@ -788,9 +792,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
-out:
|
|
|
+out_unlock:
|
|
|
spu_release(ctx);
|
|
|
-
|
|
|
+out:
|
|
|
return count;
|
|
|
}
|
|
|
|
|
@@ -905,7 +909,7 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
|
|
|
|
|
|
count = spu_acquire(ctx);
|
|
|
if (count)
|
|
|
- return count;
|
|
|
+ goto out;
|
|
|
|
|
|
/*
|
|
|
* make sure we can at least write one element, by waiting
|
|
@@ -913,14 +917,16 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
|
|
|
*/
|
|
|
count = 0;
|
|
|
if (file->f_flags & O_NONBLOCK) {
|
|
|
- if (!spu_wbox_write(ctx, wbox_data))
|
|
|
+ if (!spu_wbox_write(ctx, wbox_data)) {
|
|
|
count = -EAGAIN;
|
|
|
+ goto out_unlock;
|
|
|
+ }
|
|
|
} else {
|
|
|
count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
|
|
|
+ if (count)
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
- if (count)
|
|
|
- goto out;
|
|
|
|
|
|
/* write as much as possible */
|
|
|
for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
|
|
@@ -934,8 +940,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
-out:
|
|
|
+out_unlock:
|
|
|
spu_release(ctx);
|
|
|
+out:
|
|
|
return count;
|
|
|
}
|
|
|
|
|
@@ -1598,12 +1605,11 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
|
|
|
} else {
|
|
|
ret = spufs_wait(ctx->mfc_wq,
|
|
|
spufs_read_mfc_tagstatus(ctx, &status));
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
}
|
|
|
spu_release(ctx);
|
|
|
|
|
|
- if (ret)
|
|
|
- goto out;
|
|
|
-
|
|
|
ret = 4;
|
|
|
if (copy_to_user(buffer, &status, 4))
|
|
|
ret = -EFAULT;
|
|
@@ -1732,6 +1738,8 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
|
|
|
int status;
|
|
|
ret = spufs_wait(ctx->mfc_wq,
|
|
|
spu_send_mfc_command(ctx, cmd, &status));
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
if (status)
|
|
|
ret = status;
|
|
|
}
|
|
@@ -1785,7 +1793,7 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
|
|
|
|
|
|
ret = spu_acquire(ctx);
|
|
|
if (ret)
|
|
|
- return ret;
|
|
|
+ goto out;
|
|
|
#if 0
|
|
|
/* this currently hangs */
|
|
|
ret = spufs_wait(ctx->mfc_wq,
|
|
@@ -1794,12 +1802,13 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
|
|
|
goto out;
|
|
|
ret = spufs_wait(ctx->mfc_wq,
|
|
|
ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
|
|
|
-out:
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
#else
|
|
|
ret = 0;
|
|
|
#endif
|
|
|
spu_release(ctx);
|
|
|
-
|
|
|
+out:
|
|
|
return ret;
|
|
|
}
|
|
|
|