From a57848c95b51aa02a8466b30065c6196db4a700b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Feb 2017 15:13:04 +0000 Subject: [PATCH] drm/i915: Remove completed fences after a wait If we wait upon the full (i.e. all shared fences, or upon an exclusive fence) reservation object successfully, we know that all fences beneath it have been signaled, so long as no new fences were added whilst we slept. If the reservation_object remains the same, as detected by its seqcount, we can then reap all the fences upon completion. Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Matthew Auld Link: http://patchwork.freedesktop.org/patch/msgid/20170217151304.16665-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5f7b8c88eb7e6..d93032875f286 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -427,7 +427,9 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, long timeout, struct intel_rps_client *rps) { + unsigned int seq = __read_seqcount_begin(&resv->seq); struct dma_fence *excl; + bool prune_fences = false; if (flags & I915_WAIT_ALL) { struct dma_fence **shared; @@ -452,15 +454,26 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, for (; i < count; i++) dma_fence_put(shared[i]); kfree(shared); + + prune_fences = count && timeout >= 0; } else { excl = reservation_object_get_excl_rcu(resv); } - if (excl && timeout >= 0) + if (excl && timeout >= 0) { timeout = i915_gem_object_wait_fence(excl, flags, timeout, rps); + prune_fences = timeout >= 0; + } dma_fence_put(excl); + if (prune_fences && !__read_seqcount_retry(&resv->seq, seq)) { + reservation_object_lock(resv, NULL); + if (!__read_seqcount_retry(&resv->seq, seq)) + reservation_object_add_excl_fence(resv, NULL); + reservation_object_unlock(resv); + } + return timeout; } -- 2.39.5