That allows us to only retreive fences of write operations. Signed-off-by: Christian König <christian.koenig at amd.com> --- drivers/dma-buf/reservation.c | 19 +++++++++++++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/i915_sw_fence.c | 2 +- include/linux/reservation.h | 1 + 9 files changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 0f98384b86d4..f5dc17aa5efb 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -316,6 +316,7 @@ EXPORT_SYMBOL(reservation_object_copy_fences); * reservation_object_get_fences_rcu - Get an object's shared and exclusive * fences without update side lock held * @obj: the reservation object + * @writes_only: if true then only write operations are returned * @pfence_excl: the returned exclusive fence (or NULL) * @pshared_count: the number of shared fences returned * @pshared: the array of shared fence ptrs returned (array is krealloc'd to @@ -326,6 +327,7 @@ EXPORT_SYMBOL(reservation_object_copy_fences); * shared fences as well. Returns either zero or -ENOMEM. */ int reservation_object_get_fences_rcu(struct reservation_object *obj, + bool writes_only, struct dma_fence **pfence_excl, unsigned *pshared_count, struct dma_fence ***pshared) @@ -358,6 +360,7 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, if (sz) { struct dma_fence **nshared; + unsigned int j; nshared = krealloc(shared, sz, GFP_NOWAIT | __GFP_NOWARN); @@ -374,13 +377,20 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, } shared = nshared; shared_count = fobj ? fobj->shared_count : 0; - for (i = 0; i < shared_count; ++i) { - void *e = rcu_dereference(fobj->shared[i]); + for (i = 0, j = 0; j < shared_count; ++j) { + void *e = rcu_dereference(fobj->shared[j]); + + if (writes_only && + !reservation_object_shared_is_write(e)) + continue; shared[i] = reservation_object_shared_fence(e); if (!dma_fence_get_rcu(shared[i])) - break; + goto drop_references; + + i++; } + shared_count = i; if (!pfence_excl && fence_excl) { shared[i] = fence_excl; @@ -390,7 +400,8 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, } } - if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) { + if (read_seqcount_retry(&obj->seq, seq)) { +drop_references: while (i--) dma_fence_put(shared[i]); dma_fence_put(fence_excl); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 7d6a36bca9dd..a6d2ba4b4d2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -200,7 +200,8 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, goto unpin; } - r = reservation_object_get_fences_rcu(new_abo->tbo.resv, &work->excl, + r = reservation_object_get_fences_rcu(new_abo->tbo.resv, false, + &work->excl, &work->shared_count, &work->shared); if (unlikely(r != 0)) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c index 3a072a7a39f0..82de4eb38dff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c @@ -112,7 +112,8 @@ void amdgpu_pasid_free_delayed(struct reservation_object *resv, unsigned count; int r; - r = reservation_object_get_fences_rcu(resv, NULL, &count, &fences); + r = reservation_object_get_fences_rcu(resv, false, NULL, + &count, &fences); if (r) goto fallback; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 015613b4f98b..e1bb6f13de41 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1841,7 +1841,7 @@ static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) unsigned i, shared_count; int r; - r = reservation_object_get_fences_rcu(resv, &excl, + r = reservation_object_get_fences_rcu(resv, false, &excl, &shared_count, &shared); if (r) { /* Not enough memory to grab the fence list, as last resort diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index 5f4a872a88dd..fda8be5be574 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -188,7 +188,8 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) continue; if (bo->flags & ETNA_SUBMIT_BO_WRITE) { - ret = reservation_object_get_fences_rcu(robj, &bo->excl, + ret = reservation_object_get_fences_rcu(robj, false, + &bo->excl, &bo->nr_shared, &bo->shared); if (ret) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0415420e1cfd..85013933e827 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -517,7 +517,7 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, unsigned int count, i; int ret; - ret = reservation_object_get_fences_rcu(resv, + ret = reservation_object_get_fences_rcu(resv, false, &excl, &count, &shared); if (ret) return ret; @@ -619,7 +619,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, unsigned int count, i; int ret; - ret = reservation_object_get_fences_rcu(obj->resv, + ret = reservation_object_get_fences_rcu(obj->resv, false, &excl, &count, &shared); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index f187250e60c6..8b5d87353f54 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -981,7 +981,7 @@ i915_request_await_object(struct i915_request *to, struct dma_fence **shared; unsigned int count, i; - ret = reservation_object_get_fences_rcu(obj->resv, + ret = reservation_object_get_fences_rcu(obj->resv, false, &excl, &count, &shared); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 1de5173e53a2..1da2c5a99e47 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -499,7 +499,7 @@ int i915_sw_fence_await_reservation(struct i915_sw_fence *fence, struct dma_fence **shared; unsigned int count, i; - ret = reservation_object_get_fences_rcu(resv, + ret = reservation_object_get_fences_rcu(resv, false, &excl, &count, &shared); if (ret) return ret; diff --git a/include/linux/reservation.h b/include/linux/reservation.h index d73bf025df4b..c6defd955aa3 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -296,6 +296,7 @@ void reservation_object_add_excl_fence(struct reservation_object *obj, struct dma_fence *fence); int reservation_object_get_fences_rcu(struct reservation_object *obj, + bool writes_only, struct dma_fence **pfence_excl, unsigned *pshared_count, struct dma_fence ***pshared); -- 2.14.1