diff mbox

[2/2] drm/i915: Remove completed fences after a wait

Message ID 20170212215344.16600-2-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Feb. 12, 2017, 9:53 p.m. UTC
If we wait up on 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 <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Comments

Matthew Auld Feb. 17, 2017, 1:47 p.m. UTC | #1
On 12 February 2017 at 21:53, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> If we wait up on the full (i.e. all shared fences, or upon an exclusive fence)
s/up on/upon

> 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 <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cf8132c49600..e55a60c1afce 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -424,7 +424,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;
@@ -449,15 +451,26 @@  i915_gem_object_wait_reservation(struct reservation_object *resv,
 		for (; i < count; i++)
 			dma_fence_put(shared[i]);
 		kfree(shared);
+
+		prune_fences = 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;
 }