Commit 7e2e69ed authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Christian König
Browse files

drm/i915: Fix i915_request fence wait semantics



The i915_request fence wait behaves differently for timeout = 0
compared to expected dma-fence behavior.

i915 behavior:
- Unsignaled: -ETIME
- Signaled: 0 (= timeout)

Expected:
- Unsignaled: 0
- Signaled: 1

Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Acked-by: default avatarDaniel Vetter <daniel@ffwll.ch>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211116102431.198905-6-christian.koenig@amd.com


Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
parent 5e9ddbdc
Loading
Loading
Loading
Loading
+47 −10
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ static signed long i915_fence_wait(struct dma_fence *fence,
				   bool interruptible,
				   signed long timeout)
{
	return i915_request_wait(to_request(fence),
	return i915_request_wait_timeout(to_request(fence),
					 interruptible | I915_WAIT_PRIORITY,
					 timeout);
}
@@ -1857,21 +1857,25 @@ static void request_wait_wake(struct dma_fence *fence, struct dma_fence_cb *cb)
}

/**
 * i915_request_wait - wait until execution of request has finished
 * i915_request_wait_timeout - wait until execution of request has finished
 * @rq: the request to wait upon
 * @flags: how to wait
 * @timeout: how long to wait in jiffies
 *
 * i915_request_wait() waits for the request to be completed, for a
 * i915_request_wait_timeout() waits for the request to be completed, for a
 * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
 * unbounded wait).
 *
 * Returns the remaining time (in jiffies) if the request completed, which may
 * be zero or -ETIME if the request is unfinished after the timeout expires.
 * be zero if the request is unfinished after the timeout expires.
 * If the timeout is 0, it will return 1 if the fence is signaled.
 *
 * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
 * pending before the request completes.
 *
 * NOTE: This function has the same wait semantics as dma-fence.
 */
long i915_request_wait(struct i915_request *rq,
long i915_request_wait_timeout(struct i915_request *rq,
			       unsigned int flags,
			       long timeout)
{
@@ -1883,7 +1887,7 @@ long i915_request_wait(struct i915_request *rq,
	GEM_BUG_ON(timeout < 0);

	if (dma_fence_is_signaled(&rq->fence))
		return timeout;
		return timeout ?: 1;

	if (!timeout)
		return -ETIME;
@@ -1992,6 +1996,39 @@ long i915_request_wait(struct i915_request *rq,
	return timeout;
}

/**
 * i915_request_wait - wait until execution of request has finished
 * @rq: the request to wait upon
 * @flags: how to wait
 * @timeout: how long to wait in jiffies
 *
 * i915_request_wait() waits for the request to be completed, for a
 * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
 * unbounded wait).
 *
 * Returns the remaining time (in jiffies) if the request completed, which may
 * be zero or -ETIME if the request is unfinished after the timeout expires.
 * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
 * pending before the request completes.
 *
 * NOTE: This function behaves differently from dma-fence wait semantics for
 * timeout = 0. It returns 0 on success, and -ETIME if not signaled.
 */
long i915_request_wait(struct i915_request *rq,
		       unsigned int flags,
		       long timeout)
{
	long ret = i915_request_wait_timeout(rq, flags, timeout);

	if (!ret)
		return -ETIME;

	if (ret > 0 && !timeout)
		return 0;

	return ret;
}

static int print_sched_attr(const struct i915_sched_attr *attr,
			    char *buf, int x, int len)
{
+5 −0
Original line number Diff line number Diff line
@@ -414,6 +414,11 @@ void i915_request_unsubmit(struct i915_request *request);

void i915_request_cancel(struct i915_request *rq, int error);

long i915_request_wait_timeout(struct i915_request *rq,
			       unsigned int flags,
			       long timeout)
	__attribute__((nonnull(1)));

long i915_request_wait(struct i915_request *rq,
		       unsigned int flags,
		       long timeout)