aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKazunori Asayama <asayama@sm.sony.co.jp>2007-06-28 20:58:08 -0400
committerPaul Mackerras <paulus@samba.org>2007-07-03 01:24:46 -0400
commit933b0e35247ef0dbd1a078a0ba3705ddbbda129f (patch)
tree9f96bc933290724a26b0feeed18f7a07a141cc00 /arch
parentfe2f896d67b89a409c366c9a69e30291ab124467 (diff)
[POWERPC] spufs: Fix lost events in poll/epoll on mfc
When waiting for I/O events on mfc in an SPU context by using poll/epoll syscalls, some of the events can be lost because of wrong order of poll_wait and MFC status checks in the spufs_mfc_poll function and non-atomic update of tagwait. This fixes the problem. Signed-off-by: Kazunori Asayama <asayama@sm.sony.co.jp> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 30f7b077f347..c2814ea96af2 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1499,14 +1499,15 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1499 if (status) 1499 if (status)
1500 ret = status; 1500 ret = status;
1501 } 1501 }
1502 spu_release(ctx);
1503 1502
1504 if (ret) 1503 if (ret)
1505 goto out; 1504 goto out_unlock;
1506 1505
1507 ctx->tagwait |= 1 << cmd.tag; 1506 ctx->tagwait |= 1 << cmd.tag;
1508 ret = size; 1507 ret = size;
1509 1508
1509out_unlock:
1510 spu_release(ctx);
1510out: 1511out:
1511 return ret; 1512 return ret;
1512} 1513}
@@ -1517,14 +1518,14 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1517 u32 free_elements, tagstatus; 1518 u32 free_elements, tagstatus;
1518 unsigned int mask; 1519 unsigned int mask;
1519 1520
1521 poll_wait(file, &ctx->mfc_wq, wait);
1522
1520 spu_acquire(ctx); 1523 spu_acquire(ctx);
1521 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1524 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1522 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1525 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1523 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1526 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1524 spu_release(ctx); 1527 spu_release(ctx);
1525 1528
1526 poll_wait(file, &ctx->mfc_wq, wait);
1527
1528 mask = 0; 1529 mask = 0;
1529 if (free_elements & 0xffff) 1530 if (free_elements & 0xffff)
1530 mask |= POLLOUT | POLLWRNORM; 1531 mask |= POLLOUT | POLLWRNORM;