Commit 12fec62a authored by Chris Wilson's avatar Chris Wilson

drm: Fix syncobj handing of schedule() returning 0

After schedule() returns 0, we must do one last check of COND to
determine the reason for the wakeup with 0 jiffies remaining before
reporting the timeout -- otherwise we may lose the signal due to
scheduler delays.

References: https://bugs.freedesktop.org/show_bug.cgi?id=106690Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180920200530.2836-2-chris@chris-wilson.co.ukReviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 1664691a
...@@ -672,7 +672,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ...@@ -672,7 +672,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
{ {
struct syncobj_wait_entry *entries; struct syncobj_wait_entry *entries;
struct dma_fence *fence; struct dma_fence *fence;
signed long ret;
uint32_t signaled_count, i; uint32_t signaled_count, i;
entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
...@@ -692,7 +691,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ...@@ -692,7 +691,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
continue; continue;
} else { } else {
ret = -EINVAL; timeout = -EINVAL;
goto cleanup_entries; goto cleanup_entries;
} }
} }
...@@ -704,12 +703,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ...@@ -704,12 +703,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
} }
} }
/* Initialize ret to the max of timeout and 1. That way, the
* default return value indicates a successful wait and not a
* timeout.
*/
ret = max_t(signed long, timeout, 1);
if (signaled_count == count || if (signaled_count == count ||
(signaled_count > 0 && (signaled_count > 0 &&
!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL))) !(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL)))
...@@ -760,18 +753,17 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ...@@ -760,18 +753,17 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
goto done_waiting; goto done_waiting;
if (timeout == 0) { if (timeout == 0) {
/* If we are doing a 0 timeout wait and we got timeout = -ETIME;
* here, then we just timed out.
*/
ret = 0;
goto done_waiting; goto done_waiting;
} }
ret = schedule_timeout(ret); if (signal_pending(current)) {
timeout = -ERESTARTSYS;
goto done_waiting;
}
if (ret > 0 && signal_pending(current)) timeout = schedule_timeout(timeout);
ret = -ERESTARTSYS; } while (1);
} while (ret > 0);
done_waiting: done_waiting:
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
...@@ -788,7 +780,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ...@@ -788,7 +780,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
} }
kfree(entries); kfree(entries);
return ret; return timeout;
} }
/** /**
...@@ -829,19 +821,16 @@ static int drm_syncobj_array_wait(struct drm_device *dev, ...@@ -829,19 +821,16 @@ static int drm_syncobj_array_wait(struct drm_device *dev,
struct drm_syncobj **syncobjs) struct drm_syncobj **syncobjs)
{ {
signed long timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec); signed long timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec);
signed long ret = 0;
uint32_t first = ~0; uint32_t first = ~0;
ret = drm_syncobj_array_wait_timeout(syncobjs, timeout = drm_syncobj_array_wait_timeout(syncobjs,
wait->count_handles, wait->count_handles,
wait->flags, wait->flags,
timeout, &first); timeout, &first);
if (ret < 0) if (timeout < 0)
return ret; return timeout;
wait->first_signaled = first; wait->first_signaled = first;
if (ret == 0)
return -ETIME;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment