[Intel-gfx] [PATCH 12/22] drm/i915/gem: Allow combining submit-fences with syncobj
Chris Wilson
chris at chris-wilson.co.uk
Wed May 20 07:54:53 UTC 2020
We allow exported sync_file fences to be used as submit fences, but they
are not the only source of user fences. We also accept an array of
syncobj, and as with sync_file these are dma_fences underneath and so
feature the same set of controls. The submit-fence allows for a request
to be scheduled at the same time as the signaler, rather than as normal
after. Userspace can combine submit-fence with its own semaphores for
intra-batch scheduling.
Not exposing submit-fences to syncobj was at the time just a matter of
pragmatic expediency.
Fixes: a88b6e4cbafd ("drm/i915: Allow specification of parallel execbuf")
Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4854
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
.../gpu/drm/i915/gem/i915_gem_execbuffer.c | 14 +++++++----
drivers/gpu/drm/i915/i915_request.c | 25 +++++++++++++++++++
include/uapi/drm/i915_drm.h | 7 +++---
3 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index ce27da907dc3..91e77348282a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2431,7 +2431,7 @@ static void
__free_fence_array(struct drm_syncobj **fences, unsigned int n)
{
while (n--)
- drm_syncobj_put(ptr_mask_bits(fences[n], 2));
+ drm_syncobj_put(ptr_mask_bits(fences[n], 3));
kvfree(fences);
}
@@ -2488,7 +2488,7 @@ get_fence_array(struct drm_i915_gem_execbuffer2 *args,
BUILD_BUG_ON(~(ARCH_KMALLOC_MINALIGN - 1) &
~__I915_EXEC_FENCE_UNKNOWN_FLAGS);
- fences[n] = ptr_pack_bits(syncobj, fence.flags, 2);
+ fences[n] = ptr_pack_bits(syncobj, fence.flags, 3);
}
return fences;
@@ -2519,7 +2519,7 @@ await_fence_array(struct i915_execbuffer *eb,
struct dma_fence *fence;
unsigned int flags;
- syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ syncobj = ptr_unpack_bits(fences[n], &flags, 3);
if (!(flags & I915_EXEC_FENCE_WAIT))
continue;
@@ -2543,7 +2543,11 @@ await_fence_array(struct i915_execbuffer *eb,
spin_unlock(&syncobj->lock);
}
- err = i915_request_await_dma_fence(eb->request, fence);
+ if (flags & I915_EXEC_FENCE_WAIT_SUBMIT)
+ err = i915_request_await_execution(eb->request, fence,
+ eb->engine->bond_execute);
+ else
+ err = i915_request_await_dma_fence(eb->request, fence);
dma_fence_put(fence);
if (err < 0)
return err;
@@ -2564,7 +2568,7 @@ signal_fence_array(struct i915_execbuffer *eb,
struct drm_syncobj *syncobj;
unsigned int flags;
- syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ syncobj = ptr_unpack_bits(fences[n], &flags, 3);
if (!(flags & I915_EXEC_FENCE_SIGNAL))
continue;
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 3f7d9e4bf89f..d71728edca57 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -1425,6 +1425,27 @@ __i915_request_await_execution(struct i915_request *to,
&from->fence);
}
+static int execution_proxy(struct await_proxy *ap)
+{
+ return i915_request_await_execution(ap->request, ap->fence, ap->data);
+}
+
+static int
+i915_request_await_proxy_execution(struct i915_request *rq,
+ struct dma_fence *fence,
+ void (*hook)(struct i915_request *rq,
+ struct dma_fence *signal))
+{
+ /*
+ * We have to wait until the real request is known in order to
+ * be able to hook into its execution, as opposed to waiting for
+ * its completion.
+ */
+ return __i915_request_await_proxy(rq, fence,
+ i915_fence_timeout(rq->i915),
+ execution_proxy, hook);
+}
+
int
i915_request_await_execution(struct i915_request *rq,
struct dma_fence *fence,
@@ -1464,6 +1485,10 @@ i915_request_await_execution(struct i915_request *rq,
ret = __i915_request_await_execution(rq,
to_request(fence),
hook);
+ else if (dma_fence_is_proxy(fence))
+ ret = i915_request_await_proxy_execution(rq,
+ fence,
+ hook);
else
ret = i915_request_await_external(rq, fence);
if (ret < 0)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 14b67cd6b54b..704dd0e3bc1d 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1040,9 +1040,10 @@ struct drm_i915_gem_exec_fence {
*/
__u32 handle;
-#define I915_EXEC_FENCE_WAIT (1<<0)
-#define I915_EXEC_FENCE_SIGNAL (1<<1)
-#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
+#define I915_EXEC_FENCE_WAIT (1u << 0)
+#define I915_EXEC_FENCE_SIGNAL (1u << 1)
+#define I915_EXEC_FENCE_WAIT_SUBMIT (1u << 2)
+#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_WAIT_SUBMIT << 1))
__u32 flags;
};
--
2.20.1
More information about the Intel-gfx
mailing list