|
@@ -427,7 +427,9 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
|
|
long timeout,
|
|
long timeout,
|
|
struct intel_rps_client *rps)
|
|
struct intel_rps_client *rps)
|
|
{
|
|
{
|
|
|
|
+ unsigned int seq = __read_seqcount_begin(&resv->seq);
|
|
struct dma_fence *excl;
|
|
struct dma_fence *excl;
|
|
|
|
+ bool prune_fences = false;
|
|
|
|
|
|
if (flags & I915_WAIT_ALL) {
|
|
if (flags & I915_WAIT_ALL) {
|
|
struct dma_fence **shared;
|
|
struct dma_fence **shared;
|
|
@@ -452,15 +454,26 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
|
|
for (; i < count; i++)
|
|
for (; i < count; i++)
|
|
dma_fence_put(shared[i]);
|
|
dma_fence_put(shared[i]);
|
|
kfree(shared);
|
|
kfree(shared);
|
|
|
|
+
|
|
|
|
+ prune_fences = count && timeout >= 0;
|
|
} else {
|
|
} else {
|
|
excl = reservation_object_get_excl_rcu(resv);
|
|
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);
|
|
timeout = i915_gem_object_wait_fence(excl, flags, timeout, rps);
|
|
|
|
+ prune_fences = timeout >= 0;
|
|
|
|
+ }
|
|
|
|
|
|
dma_fence_put(excl);
|
|
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;
|
|
return timeout;
|
|
}
|
|
}
|
|
|
|
|