Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 933b0e35 authored by Kazunori Asayama's avatar Kazunori Asayama Committed by Paul Mackerras
Browse files

[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: default avatarKazunori Asayama <asayama@sm.sony.co.jp>
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent fe2f896d
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1499,14 +1499,15 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
		if (status)
			ret = status;
	}
	spu_release(ctx);

	if (ret)
		goto out;
		goto out_unlock;

	ctx->tagwait |= 1 << cmd.tag;
	ret = size;

out_unlock:
	spu_release(ctx);
out:
	return ret;
}
@@ -1517,14 +1518,14 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
	u32 free_elements, tagstatus;
	unsigned int mask;

	poll_wait(file, &ctx->mfc_wq, wait);

	spu_acquire(ctx);
	ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
	free_elements = ctx->ops->get_mfc_free_elements(ctx);
	tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
	spu_release(ctx);

	poll_wait(file, &ctx->mfc_wq, wait);

	mask = 0;
	if (free_elements & 0xffff)
		mask |= POLLOUT | POLLWRNORM;