浏览代码

drm/i915: Check waiter->seqno carefully in case of preemption

If preemption occurs at precisely the right moment, we may decide that
the wait is complete even though the wait's request is no longer
executing (having been preempted). We handle this situation by double
checking that request following deciding whether the wait is complete.

Reported-by: Michał Winiarski <michal.winiarski@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170918162734.21294-2-chris@chris-wilson.co.uk
Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>
Chris Wilson 8 年之前
父节点
当前提交
de4d2106f8
共有 1 个文件被更改,包括 5 次插入2 次删除
  1. 5 2
      drivers/gpu/drm/i915/i915_irq.c

+ 5 - 2
drivers/gpu/drm/i915/i915_irq.c

@@ -1053,10 +1053,13 @@ static void notify_ring(struct intel_engine_cs *engine)
 		 */
 		 */
 		if (i915_seqno_passed(intel_engine_get_seqno(engine),
 		if (i915_seqno_passed(intel_engine_get_seqno(engine),
 				      wait->seqno)) {
 				      wait->seqno)) {
+			struct drm_i915_gem_request *waiter = wait->request;
+
 			wakeup = true;
 			wakeup = true;
 			if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
 			if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
-				      &wait->request->fence.flags))
-				rq = i915_gem_request_get(wait->request);
+				      &waiter->fence.flags) &&
+			    intel_wait_check_request(wait, waiter))
+				rq = i915_gem_request_get(waiter);
 		}
 		}
 
 
 		if (wakeup)
 		if (wakeup)