diff options
Diffstat (limited to 'drivers/gpu/drm/i915/gem/i915_gem_busy.c')
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_busy.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_busy.c b/drivers/gpu/drm/i915/gem/i915_gem_busy.c index a2aff1d8290e..3d4f5775a4ba 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_busy.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_busy.c @@ -83,8 +83,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_busy *args = data; struct drm_i915_gem_object *obj; struct dma_resv_list *list; - unsigned int i, shared_count; - struct dma_fence *excl; + unsigned int seq; int err; err = -ENOENT; @@ -110,18 +109,29 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * to report the overall busyness. This is what the wait-ioctl does. * */ - dma_resv_fences(obj->base.resv, &excl, &list, &shared_count); +retry: + seq = raw_read_seqcount(&obj->base.resv->seq); /* Translate the exclusive fence to the READ *and* WRITE engine */ - args->busy = busy_check_writer(excl); + args->busy = + busy_check_writer(rcu_dereference(obj->base.resv->fence_excl)); /* Translate shared fences to READ set of engines */ - for (i = 0; i < shared_count; ++i) { - struct dma_fence *fence = rcu_dereference(list->shared[i]); + list = rcu_dereference(obj->base.resv->fence); + if (list) { + unsigned int shared_count = list->shared_count, i; - args->busy |= busy_check_reader(fence); + for (i = 0; i < shared_count; ++i) { + struct dma_fence *fence = + rcu_dereference(list->shared[i]); + + args->busy |= busy_check_reader(fence); + } } + if (args->busy && read_seqcount_retry(&obj->base.resv->seq, seq)) + goto retry; + err = 0; out: rcu_read_unlock(); |