Commit 3136deb7 authored by Lionel Landwerlin's avatar Lionel Landwerlin Committed by Chris Wilson

drm/i915: Peel dma-fence-chains for await

To allow faster engine to engine synchronization, peel the layer of
dma-fence-chain to expose potential i915 fences so that the
i915_request code can emit HW semaphore wait/signal operations in the
ring which is faster than waking up the host to submit unblocked
workloads after interrupt notification.

This is similar to the peeling we do for e.g. dma_fence_array.
Signed-off-by: default avatarLionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200508185448.29709-1-chris@chris-wilson.co.uk
parent e41627db
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include <linux/dma-fence-array.h> #include <linux/dma-fence-array.h>
#include <linux/dma-fence-chain.h>
#include <linux/irq_work.h> #include <linux/irq_work.h>
#include <linux/prefetch.h> #include <linux/prefetch.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -1068,13 +1069,39 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) ...@@ -1068,13 +1069,39 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from)
} }
static int static int
i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence)
{ {
return i915_sw_fence_await_dma_fence(&rq->submit, fence, return i915_sw_fence_await_dma_fence(&rq->submit, fence,
fence->context ? I915_FENCE_TIMEOUT : 0, fence->context ? I915_FENCE_TIMEOUT : 0,
I915_FENCE_GFP); I915_FENCE_GFP);
} }
static int
i915_request_await_external(struct i915_request *rq, struct dma_fence *fence)
{
struct dma_fence *iter;
int err = 0;
if (!to_dma_fence_chain(fence))
return __i915_request_await_external(rq, fence);
dma_fence_chain_for_each(iter, fence) {
struct dma_fence_chain *chain = to_dma_fence_chain(iter);
if (!dma_fence_is_i915(chain->fence)) {
err = __i915_request_await_external(rq, iter);
break;
}
err = i915_request_await_dma_fence(rq, chain->fence);
if (err < 0)
break;
}
dma_fence_put(iter);
return err;
}
int int
i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
{ {
......
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