Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200508185448.29709-1-chris@chris-wilson.co.uk

authored by

Lionel Landwerlin and committed by
Chris Wilson
3136deb7 e41627db

+28 -1
+28 -1
drivers/gpu/drm/i915/i915_request.c
··· 23 23 */ 24 24 25 25 #include <linux/dma-fence-array.h> 26 + #include <linux/dma-fence-chain.h> 26 27 #include <linux/irq_work.h> 27 28 #include <linux/prefetch.h> 28 29 #include <linux/sched.h> ··· 1069 1068 } 1070 1069 1071 1070 static int 1072 - i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1071 + __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1073 1072 { 1074 1073 return i915_sw_fence_await_dma_fence(&rq->submit, fence, 1075 1074 fence->context ? I915_FENCE_TIMEOUT : 0, 1076 1075 I915_FENCE_GFP); 1076 + } 1077 + 1078 + static int 1079 + i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1080 + { 1081 + struct dma_fence *iter; 1082 + int err = 0; 1083 + 1084 + if (!to_dma_fence_chain(fence)) 1085 + return __i915_request_await_external(rq, fence); 1086 + 1087 + dma_fence_chain_for_each(iter, fence) { 1088 + struct dma_fence_chain *chain = to_dma_fence_chain(iter); 1089 + 1090 + if (!dma_fence_is_i915(chain->fence)) { 1091 + err = __i915_request_await_external(rq, iter); 1092 + break; 1093 + } 1094 + 1095 + err = i915_request_await_dma_fence(rq, chain->fence); 1096 + if (err < 0) 1097 + break; 1098 + } 1099 + 1100 + dma_fence_put(iter); 1101 + return err; 1077 1102 } 1078 1103 1079 1104 int