@@ -2432,7 +2432,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);
}
@@ -2489,7 +2489,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;
@@ -2520,7 +2520,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;
@@ -2544,7 +2544,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;
@@ -2565,7 +2569,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;
@@ -1433,6 +1433,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,
@@ -1472,6 +1493,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)
@@ -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;
};