[Mesa-dev] [PATCH 7/8] radv/amdgpu: Use reference counting for bos.

Nicolai Hähnle nhaehnle at gmail.com
Wed Feb 8 09:14:29 UTC 2017


On 05.02.2017 12:43, Bas Nieuwenhuizen wrote:
> Per the Vulkan spec, memory objects may be deleted before the buffers
> and images using them are deleted, although those resources then
> cannot be used except for deletion themselves.
>
> For the virtual buffers, we need to access them on resource destruction
> to unmap the regions, so this results in a use-after-free. Implement
> reference counting to avoid this.

So there's really no requirement to remove the bindings before deleting 
the memory objects? Sucks :/

Cheers,
Nicolai

>
> Signed-off-by: Bas Nieuwenhuizen <basni at google.com>
> ---
>  src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 10 ++++++++++
>  src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h |  1 +
>  2 files changed, 11 insertions(+)
>
> diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c
> index d5bce304510..6519b096fcc 100644
> --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c
> +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c
> @@ -34,6 +34,11 @@
>  #include <amdgpu_drm.h>
>  #include <inttypes.h>
>
> +#include "util/u_atomic.h"
> +
> +
> +static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys_bo *_bo);
> +
>  static void
>  radv_amdgpu_winsys_virtual_map(struct radv_amdgpu_winsys_bo *bo,
>                                 const struct radv_amdgpu_map_range *range)
> @@ -43,6 +48,7 @@ radv_amdgpu_winsys_virtual_map(struct radv_amdgpu_winsys_bo *bo,
>  	if (!range->bo)
>  		return; /* TODO: PRT mapping */
>
> +	p_atomic_inc(&range->bo->ref_count);
>  	int r = amdgpu_bo_va_op(range->bo->bo, range->bo_offset, range->size,
>  	                        range->offset + bo->va, 0, AMDGPU_VA_OP_MAP);
>  	if (r)
> @@ -62,6 +68,7 @@ radv_amdgpu_winsys_virtual_unmap(struct radv_amdgpu_winsys_bo *bo,
>  	                        range->offset + bo->va, 0, AMDGPU_VA_OP_UNMAP);
>  	if (r)
>  		abort();
> +	radv_amdgpu_winsys_bo_destroy((struct radeon_winsys_bo *)range->bo);
>  }
>
>  static void
> @@ -193,6 +200,8 @@ static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys_bo *_bo)
>  {
>  	struct radv_amdgpu_winsys_bo *bo = radv_amdgpu_winsys_bo(_bo);
>
> +	if (p_atomic_dec_return(&bo->ref_count))
> +		return;
>  	if (bo->is_virtual) {
>  		for (uint32_t i = 0; i < bo->range_count; ++i) {
>  			radv_amdgpu_winsys_virtual_unmap(bo, bo->ranges + i);
> @@ -254,6 +263,7 @@ radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws,
>  	bo->size = size;
>  	bo->ws = ws;
>  	bo->is_virtual = !!(flags & RADEON_FLAG_VIRTUAL);
> +	bo->ref_count = 1;
>
>  	if (flags & RADEON_FLAG_VIRTUAL) {
>  		bo->ranges = realloc(NULL, sizeof(struct radv_amdgpu_map_range));
> diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h
> index c7d484bc8dd..4512e76b333 100644
> --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h
> +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h
> @@ -45,6 +45,7 @@ struct radv_amdgpu_winsys_bo {
>  	uint64_t size;
>  	struct radv_amdgpu_winsys *ws;
>  	bool is_virtual;
> +	int ref_count;
>
>  	union {
>  		/* physical bo */
>



More information about the mesa-dev mailing list