|
@@ -556,6 +556,16 @@ int sync_fence_cancel_async(struct sync_fence *fence,
|
|
|
}
|
|
|
EXPORT_SYMBOL(sync_fence_cancel_async);
|
|
|
|
|
|
+static bool sync_fence_check(struct sync_fence *fence)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Make sure that reads to fence->status are ordered with the
|
|
|
+ * wait queue event triggering
|
|
|
+ */
|
|
|
+ smp_rmb();
|
|
|
+ return fence->status != 0;
|
|
|
+}
|
|
|
+
|
|
|
int sync_fence_wait(struct sync_fence *fence, long timeout)
|
|
|
{
|
|
|
int err = 0;
|
|
@@ -563,7 +573,7 @@ int sync_fence_wait(struct sync_fence *fence, long timeout)
|
|
|
if (timeout > 0) {
|
|
|
timeout = msecs_to_jiffies(timeout);
|
|
|
err = wait_event_interruptible_timeout(fence->wq,
|
|
|
- fence->status != 0,
|
|
|
+ sync_fence_check(fence),
|
|
|
timeout);
|
|
|
} else if (timeout < 0) {
|
|
|
err = wait_event_interruptible(fence->wq, fence->status != 0);
|
|
@@ -630,6 +640,12 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
|
|
|
|
|
|
poll_wait(file, &fence->wq, wait);
|
|
|
|
|
|
+ /*
|
|
|
+ * Make sure that reads to fence->status are ordered with the
|
|
|
+ * wait queue event triggering
|
|
|
+ */
|
|
|
+ smp_rmb();
|
|
|
+
|
|
|
if (fence->status == 1)
|
|
|
return POLLIN;
|
|
|
else if (fence->status < 0)
|