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

drm/i915: Prevent using semaphores to chain up to external fences

The downside of using semaphores is that we lose metadata passing
along the signaling chain. This is particularly nasty when we
need to pass along a fatal error such as EFAULT or EDEADLK. For
fatal errors we want to scrub the request before it is executed,
which means that we cannot preload the request onto HW and have
it wait upon a semaphore.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200508092933.738-3-chris@chris-wilson.co.uk

+27
+26
drivers/gpu/drm/i915/i915_request.c
··· 1003 1003 if (!rcu_access_pointer(from->hwsp_cacheline)) 1004 1004 goto await_fence; 1005 1005 1006 + /* 1007 + * If this or its dependents are waiting on an external fence 1008 + * that may fail catastrophically, then we want to avoid using 1009 + * sempahores as they bypass the fence signaling metadata, and we 1010 + * lose the fence->error propagation. 1011 + */ 1012 + if (from->sched.flags & I915_SCHED_HAS_EXTERNAL_CHAIN) 1013 + goto await_fence; 1014 + 1006 1015 /* Just emit the first semaphore we see as request space is limited. */ 1007 1016 if (already_busywaiting(to) & mask) 1008 1017 goto await_fence; ··· 1074 1065 return ret; 1075 1066 } 1076 1067 1068 + if (from->sched.flags & I915_SCHED_HAS_EXTERNAL_CHAIN) 1069 + to->sched.flags |= I915_SCHED_HAS_EXTERNAL_CHAIN; 1070 + 1077 1071 return 0; 1072 + } 1073 + 1074 + static void mark_external(struct i915_request *rq) 1075 + { 1076 + /* 1077 + * The downside of using semaphores is that we lose metadata passing 1078 + * along the signaling chain. This is particularly nasty when we 1079 + * need to pass along a fatal error such as EFAULT or EDEADLK. For 1080 + * fatal errors we want to scrub the request before it is executed, 1081 + * which means that we cannot preload the request onto HW and have 1082 + * it wait upon a semaphore. 1083 + */ 1084 + rq->sched.flags |= I915_SCHED_HAS_EXTERNAL_CHAIN; 1078 1085 } 1079 1086 1080 1087 static int 1081 1088 __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1082 1089 { 1090 + mark_external(rq); 1083 1091 return i915_sw_fence_await_dma_fence(&rq->submit, fence, 1084 1092 fence->context ? I915_FENCE_TIMEOUT : 0, 1085 1093 I915_FENCE_GFP);
+1
drivers/gpu/drm/i915/i915_scheduler_types.h
··· 66 66 struct i915_sched_attr attr; 67 67 unsigned int flags; 68 68 #define I915_SCHED_HAS_SEMAPHORE_CHAIN BIT(0) 69 + #define I915_SCHED_HAS_EXTERNAL_CHAIN BIT(1) 69 70 intel_engine_mask_t semaphores; 70 71 }; 71 72