Message ID | 20190821123147.110736-6-christian.koenig@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/10] dma-buf: make to_dma_fence_array NULL safe | expand |
Quoting Christian König (2019-08-21 13:31:42) > Add a new dma_resv_prune_fences() function to improve memory management. > > Signed-off-by: Christian König <christian.koenig@amd.com> > --- > drivers/dma-buf/dma-resv.c | 37 ++++++++++++++++++++++ > drivers/gpu/drm/i915/gem/i915_gem_wait.c | 3 +- > drivers/gpu/drm/i915/i915_gem_batch_pool.c | 2 +- > drivers/gpu/drm/i915/i915_vma.c | 3 +- > drivers/gpu/drm/ttm/ttm_bo.c | 2 +- > include/linux/dma-resv.h | 1 + > 6 files changed, 42 insertions(+), 6 deletions(-) > > diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c > index 42a8f3f11681..24adc32d36d4 100644 > --- a/drivers/dma-buf/dma-resv.c > +++ b/drivers/dma-buf/dma-resv.c > @@ -301,6 +301,43 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) > } > EXPORT_SYMBOL(dma_resv_add_excl_fence); > > +/** > + * dma_resv_prune_fences - prune signaled fences from the resv object > + * @obj: the reservation object to prune > + * > + * Prune all signaled fences from the reservation object. > + */ > +void dma_resv_prune_fences(struct dma_resv *obj) > +{ > + struct dma_resv_list *list; > + struct dma_fence *fence; > + unsigned int i; > + > + dma_resv_assert_held(obj); > + > + fence = dma_resv_get_excl(obj); > + if (dma_fence_is_signaled(fence)) { > + RCU_INIT_POINTER(obj->fence_excl, NULL); > + dma_fence_put(fence); > + } > + > + list = dma_resv_get_list(obj); > + if (!list) > + return; > + > + for (i = 0; i < list->shared_count; ++i) { > + fence = rcu_dereference_protected(list->shared[i], > + dma_resv_held(obj)); > + > + if (!dma_fence_is_signaled(fence)) > + continue; > + > + RCU_INIT_POINTER(list->shared[i], dma_fence_get_stub()); > + dma_fence_put(fence); Not worth reusing the compaction logic from add_shared_fence? -Chris
Quoting Chris Wilson (2019-08-21 15:55:08) > Quoting Christian König (2019-08-21 13:31:42) > > Add a new dma_resv_prune_fences() function to improve memory management. > > > > Signed-off-by: Christian König <christian.koenig@amd.com> > > --- > > drivers/dma-buf/dma-resv.c | 37 ++++++++++++++++++++++ > > drivers/gpu/drm/i915/gem/i915_gem_wait.c | 3 +- > > drivers/gpu/drm/i915/i915_gem_batch_pool.c | 2 +- > > drivers/gpu/drm/i915/i915_vma.c | 3 +- > > drivers/gpu/drm/ttm/ttm_bo.c | 2 +- > > include/linux/dma-resv.h | 1 + > > 6 files changed, 42 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c > > index 42a8f3f11681..24adc32d36d4 100644 > > --- a/drivers/dma-buf/dma-resv.c > > +++ b/drivers/dma-buf/dma-resv.c > > @@ -301,6 +301,43 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) > > } > > EXPORT_SYMBOL(dma_resv_add_excl_fence); > > > > +/** > > + * dma_resv_prune_fences - prune signaled fences from the resv object > > + * @obj: the reservation object to prune > > + * > > + * Prune all signaled fences from the reservation object. > > + */ > > +void dma_resv_prune_fences(struct dma_resv *obj) > > +{ > > + struct dma_resv_list *list; > > + struct dma_fence *fence; > > + unsigned int i; > > + > > + dma_resv_assert_held(obj); > > + > > + fence = dma_resv_get_excl(obj); > > + if (dma_fence_is_signaled(fence)) { > > + RCU_INIT_POINTER(obj->fence_excl, NULL); > > + dma_fence_put(fence); > > + } > > + > > + list = dma_resv_get_list(obj); > > + if (!list) > > + return; > > + > > + for (i = 0; i < list->shared_count; ++i) { > > + fence = rcu_dereference_protected(list->shared[i], > > + dma_resv_held(obj)); > > + > > + if (!dma_fence_is_signaled(fence)) > > + continue; > > + > > + RCU_INIT_POINTER(list->shared[i], dma_fence_get_stub()); > > + dma_fence_put(fence); > > Not worth reusing the compaction logic from add_shared_fence? Scratch that, you're going to rewrite the shared fence container. -Chris
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 42a8f3f11681..24adc32d36d4 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -301,6 +301,43 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) } EXPORT_SYMBOL(dma_resv_add_excl_fence); +/** + * dma_resv_prune_fences - prune signaled fences from the resv object + * @obj: the reservation object to prune + * + * Prune all signaled fences from the reservation object. + */ +void dma_resv_prune_fences(struct dma_resv *obj) +{ + struct dma_resv_list *list; + struct dma_fence *fence; + unsigned int i; + + dma_resv_assert_held(obj); + + fence = dma_resv_get_excl(obj); + if (dma_fence_is_signaled(fence)) { + RCU_INIT_POINTER(obj->fence_excl, NULL); + dma_fence_put(fence); + } + + list = dma_resv_get_list(obj); + if (!list) + return; + + for (i = 0; i < list->shared_count; ++i) { + fence = rcu_dereference_protected(list->shared[i], + dma_resv_held(obj)); + + if (!dma_fence_is_signaled(fence)) + continue; + + RCU_INIT_POINTER(list->shared[i], dma_fence_get_stub()); + dma_fence_put(fence); + } +} +EXPORT_SYMBOL(dma_resv_prune_fences); + /** * dma_resv_copy_fences - Copy all fences from src to dst. * @dst: the destination reservation object diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c index 8af55cd3e690..a76d36f8fb77 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c @@ -85,8 +85,7 @@ i915_gem_object_wait_reservation(struct dma_resv *resv, * signaled. */ if (prune_fences && dma_resv_trylock(resv)) { - if (dma_resv_test_signaled_rcu(resv, true)) - dma_resv_add_excl_fence(resv, NULL); + dma_resv_prune_fences(resv); dma_resv_unlock(resv); } diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c index 5f82a763e64c..274cf5b19fc9 100644 --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c @@ -114,7 +114,7 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, */ if (rcu_access_pointer(resv->fence)) { dma_resv_lock(resv, NULL); - dma_resv_add_excl_fence(resv, NULL); + dma_resv_prune_fences(resv); dma_resv_unlock(resv); } } diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index ebfd03d117cd..fcbe433a968c 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -100,8 +100,7 @@ static void __i915_vma_retire(struct i915_active *ref) /* Prune the shared fence arrays iff completely idle (inc. external) */ if (dma_resv_trylock(obj->base.resv)) { - if (dma_resv_test_signaled_rcu(obj->base.resv, true)) - dma_resv_add_excl_fence(obj->base.resv, NULL); + dma_resv_prune_fences(obj->base.resv); dma_resv_unlock(obj->base.resv); } diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 58d1f2b28132..f78f52cc2e6d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1818,7 +1818,7 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, if (timeout == 0) return -EBUSY; - dma_resv_add_excl_fence(bo->base.resv, NULL); + dma_resv_prune_fences(bo->base.resv); return 0; } EXPORT_SYMBOL(ttm_bo_wait); diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h index ee50d10f052b..03b0f95682b0 100644 --- a/include/linux/dma-resv.h +++ b/include/linux/dma-resv.h @@ -279,6 +279,7 @@ int dma_resv_reserve_shared(struct dma_resv *obj, unsigned int num_fences); void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence); void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence); +void dma_resv_prune_fences(struct dma_resv *obj); int dma_resv_get_fences_rcu(struct dma_resv *obj, struct dma_fence **pfence_excl,
Add a new dma_resv_prune_fences() function to improve memory management. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/dma-buf/dma-resv.c | 37 ++++++++++++++++++++++ drivers/gpu/drm/i915/gem/i915_gem_wait.c | 3 +- drivers/gpu/drm/i915/i915_gem_batch_pool.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 3 +- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- include/linux/dma-resv.h | 1 + 6 files changed, 42 insertions(+), 6 deletions(-)