From: John Harrison <John.C.Harrison@xxxxxxxxx> The completion status for all entries in the request list is updated on demand. This occurs whenever the code queries the completion status of a given request and a new seqno value has popped out of the hardware. Unfortuntately, not all such queries are done with the driver mutex lock held. Therefore there is a race condition between the query processing and the retired request removal code which can result in a dodgy pointer dereference. The solution is to spinlock around those two points - the actual list entry removal and the potentially asynchronous query. This ensures that the query will never see a node that is in the process of being destroyed. For: VIZ-4377 Signed-off-by: John Harrison <John.C.Harrison@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 035735a..c4facbd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2491,7 +2491,12 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv, static void i915_gem_free_request(struct drm_i915_gem_request *request) { + unsigned long flags; + + spin_lock_irqsave(&request->ring->reqlist_lock, flags); list_del(&request->list); + spin_unlock_irqrestore(&request->ring->reqlist_lock, flags); + i915_gem_request_remove_from_client(request); i915_gem_request_unreference(request); @@ -2647,12 +2652,14 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring, bool lazy_coherency) { struct drm_i915_gem_request *req; + unsigned long flags; u32 seqno; seqno = ring->get_seqno(ring, lazy_coherency); if (seqno == ring->last_read_seqno) return; + spin_lock_irqsave(&ring->reqlist_lock, flags); list_for_each_entry(req, &ring->request_list, list) { if (req->complete) continue; @@ -2660,6 +2667,7 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring, if (i915_seqno_passed(seqno, req->seqno)) req->complete = true; } + spin_unlock_irqrestore(&ring->reqlist_lock, flags); ring->last_read_seqno = seqno; } -- 1.7.9.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx