drm/i915: Only signal from interrupt when requested
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Jun 2018 20:13:04 +0000 (21:13 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Jun 2018 19:56:35 +0000 (20:56 +0100)
Avoid calling dma_fence_signal() from inside the interrupt if we haven't
enabled signaling on the request.

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/20180627201304.15817-4-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_request.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index c81b4c1877cce4030f6af7955f2215f1763e4cef..4be56aec99b3432565a7292d4d350fafb97c3b1e 100644 (file)
@@ -1182,7 +1182,8 @@ static void notify_ring(struct intel_engine_cs *engine)
                if (i915_seqno_passed(seqno, wait->seqno)) {
                        struct i915_request *waiter = wait->request;
 
-                       if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+                       if (waiter &&
+                           !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
                                      &waiter->fence.flags) &&
                            intel_wait_check_request(wait, waiter))
                                rq = i915_request_get(waiter);
@@ -1205,8 +1206,11 @@ static void notify_ring(struct intel_engine_cs *engine)
        spin_unlock(&engine->breadcrumbs.irq_lock);
 
        if (rq) {
-               dma_fence_signal(&rq->fence);
+               spin_lock(&rq->lock);
+               dma_fence_signal_locked(&rq->fence);
                GEM_BUG_ON(!i915_request_completed(rq));
+               spin_unlock(&rq->lock);
+
                i915_request_put(rq);
        }
 
index 39b296878ba2872a47da64bf2190a97777311f39..a2f7e9358450fb46c029e466ef54b81758408825 100644 (file)
@@ -1285,7 +1285,7 @@ long i915_request_wait(struct i915_request *rq,
        if (flags & I915_WAIT_LOCKED)
                add_wait_queue(errq, &reset);
 
-       intel_wait_init(&wait, rq);
+       intel_wait_init(&wait);
 
 restart:
        do {
index 44ac90ec540c21fadc6749ed2d7e4b05740480bb..78f01a35823afe59393b90b070f4f9bef4690db2 100644 (file)
@@ -928,11 +928,10 @@ static inline u32 intel_hws_preempt_done_address(struct intel_engine_cs *engine)
 /* intel_breadcrumbs.c -- user interrupt bottom-half for waiters */
 int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine);
 
-static inline void intel_wait_init(struct intel_wait *wait,
-                                  struct i915_request *rq)
+static inline void intel_wait_init(struct intel_wait *wait)
 {
        wait->tsk = current;
-       wait->request = rq;
+       wait->request = NULL;
 }
 
 static inline void intel_wait_init_for_seqno(struct intel_wait *wait, u32 seqno)