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

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.comSigned-off-by: default avatarChristian König <christian.koenig@amd.com>
parent 5e9ddbdc
...@@ -96,9 +96,9 @@ static signed long i915_fence_wait(struct dma_fence *fence, ...@@ -96,9 +96,9 @@ static signed long i915_fence_wait(struct dma_fence *fence,
bool interruptible, bool interruptible,
signed long timeout) signed long timeout)
{ {
return i915_request_wait(to_request(fence), return i915_request_wait_timeout(to_request(fence),
interruptible | I915_WAIT_PRIORITY, interruptible | I915_WAIT_PRIORITY,
timeout); timeout);
} }
struct kmem_cache *i915_request_slab_cache(void) struct kmem_cache *i915_request_slab_cache(void)
...@@ -1857,23 +1857,27 @@ static void request_wait_wake(struct dma_fence *fence, struct dma_fence_cb *cb) ...@@ -1857,23 +1857,27 @@ 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 * @rq: the request to wait upon
* @flags: how to wait * @flags: how to wait
* @timeout: how long to wait in jiffies * @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 * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
* unbounded wait). * unbounded wait).
* *
* Returns the remaining time (in jiffies) if the request completed, which may * 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 * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
* pending before the request completes. * 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, unsigned int flags,
long timeout) long timeout)
{ {
const int state = flags & I915_WAIT_INTERRUPTIBLE ? const int state = flags & I915_WAIT_INTERRUPTIBLE ?
TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
...@@ -1883,7 +1887,7 @@ long i915_request_wait(struct i915_request *rq, ...@@ -1883,7 +1887,7 @@ long i915_request_wait(struct i915_request *rq,
GEM_BUG_ON(timeout < 0); GEM_BUG_ON(timeout < 0);
if (dma_fence_is_signaled(&rq->fence)) if (dma_fence_is_signaled(&rq->fence))
return timeout; return timeout ?: 1;
if (!timeout) if (!timeout)
return -ETIME; return -ETIME;
...@@ -1992,6 +1996,39 @@ long i915_request_wait(struct i915_request *rq, ...@@ -1992,6 +1996,39 @@ long i915_request_wait(struct i915_request *rq,
return timeout; 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, static int print_sched_attr(const struct i915_sched_attr *attr,
char *buf, int x, int len) char *buf, int x, int len)
{ {
......
...@@ -414,6 +414,11 @@ void i915_request_unsubmit(struct i915_request *request); ...@@ -414,6 +414,11 @@ void i915_request_unsubmit(struct i915_request *request);
void i915_request_cancel(struct i915_request *rq, int error); 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, long i915_request_wait(struct i915_request *rq,
unsigned int flags, unsigned int flags,
long timeout) long timeout)
......
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