diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7a81ae2f00f90d050e559a5221b365c4c6ec90b6..36d407848f28d56a0bb88a3053d056917aaffd18 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1991,6 +1991,8 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, * an emission time with seqnos for tracking how far ahead of the GPU we are. */ struct drm_i915_gem_request { + struct kref ref; + /** On Which ring this request was generated */ struct intel_engine_cs *ring; @@ -2020,6 +2022,32 @@ struct drm_i915_gem_request { struct list_head client_list; }; +void i915_gem_request_free(struct kref *req_ref); + +static inline void +i915_gem_request_reference(struct drm_i915_gem_request *req) +{ + kref_get(&req->ref); +} + +static inline void +i915_gem_request_unreference(struct drm_i915_gem_request *req) +{ + kref_put(&req->ref, i915_gem_request_free); +} + +static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst, + struct drm_i915_gem_request *src) +{ + if (src) + i915_gem_request_reference(src); + + if (*pdst) + i915_gem_request_unreference(*pdst); + + *pdst = src; +} + struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fa3f907ce229407538039e19084d3fc6000c4a57..ef45e2eac95230f9c8ec801ad598c2c3805e8a19 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2569,21 +2569,30 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv, static void i915_gem_free_request(struct drm_i915_gem_request *request) { - struct intel_context *ctx = request->ctx; - list_del(&request->list); i915_gem_request_remove_from_client(request); + i915_gem_request_unreference(request); +} + +void i915_gem_request_free(struct kref *req_ref) +{ + struct drm_i915_gem_request *req = container_of(req_ref, + typeof(*req), ref); + struct intel_context *ctx = req->ctx; + if (ctx) { if (i915.enable_execlists) { - struct intel_engine_cs *ring = request->ring; + struct intel_engine_cs *ring = req->ring; if (ctx != ring->default_context) intel_lr_context_unpin(ring, ctx); } + i915_gem_context_unreference(ctx); } - kfree(request); + + kfree(req); } struct drm_i915_gem_request * @@ -2671,8 +2680,7 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, } /* These may not have been flush before the reset, do so now */ - kfree(ring->preallocated_lazy_request); - ring->preallocated_lazy_request = NULL; + i915_gem_request_assign(&ring->preallocated_lazy_request, NULL); ring->outstanding_lazy_seqno = 0; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cc49b8492ee4ce558d2f0bd514a36d3092c4a563..56c275d0a610210462e5cb65c1a310d060eca2bc 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -905,6 +905,8 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, } } + kref_init(&request->ref); + ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno); if (ret) { intel_lr_context_unpin(ring, ctx); @@ -1374,7 +1376,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) intel_logical_ring_stop(ring); WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); - ring->preallocated_lazy_request = NULL; + i915_gem_request_assign(&ring->preallocated_lazy_request, NULL); ring->outstanding_lazy_seqno = 0; if (ring->cleanup) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9fe13075e5f95a2b333a2e46c6cfc9ba75bce3bc..fbeaa3ad6208aa37c55c13d6f29cdec720f8ad1a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1870,7 +1870,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) intel_unpin_ringbuffer_obj(ringbuf); intel_destroy_ringbuffer_obj(ringbuf); - ring->preallocated_lazy_request = NULL; + i915_gem_request_assign(&ring->preallocated_lazy_request, NULL); ring->outstanding_lazy_seqno = 0; if (ring->cleanup) @@ -2043,6 +2043,8 @@ intel_ring_alloc_seqno(struct intel_engine_cs *ring) if (request == NULL) return -ENOMEM; + kref_init(&request->ref); + ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno); if (ret) { kfree(request);