From: Michel Dänzer <michel.daenzer@xxxxxxx> We can just walk the lists of struct amdgpu_bo/device to find out if there are any references left. Signed-off-by: Michel Dänzer <michel.daenzer@xxxxxxx> --- amdgpu/amdgpu_bo.c | 14 +++++++++++--- amdgpu/amdgpu_device.c | 30 ++++++++++++++++++++++-------- amdgpu/amdgpu_internal.h | 2 -- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c index f40df484..332ce4be 100644 --- a/amdgpu/amdgpu_bo.c +++ b/amdgpu/amdgpu_bo.c @@ -65,7 +65,6 @@ static int amdgpu_core_bo_create(struct amdgpu_core_device *dev, return r; } - bo->refcount = 1; bo->alloc_size = size; bo->handle = handle; pthread_mutex_init(&bo->cpu_access_mutex, NULL); @@ -95,7 +94,6 @@ static int amdgpu_bo_create(amdgpu_device_handle user_dev, goto out; } } - bo->refcount++; } else { r = amdgpu_core_bo_create(dev, size, handle, &bo); if (r) @@ -466,8 +464,18 @@ static void amdgpu_core_bo_free(struct amdgpu_bo *user_bo) { struct amdgpu_core_device *dev = user_bo->dev->core; struct amdgpu_core_bo *bo = user_bo->core; + struct amdgpu_bo *iter_bo; - if (--bo->refcount == 0) { + /* Are there any other user BOs left referencing the same core BO? */ + for (iter_bo = bo->user_bos; iter_bo; iter_bo = iter_bo->next) { + if (iter_bo == user_bo) + continue; + + if (iter_bo->core == bo) + break; + } + + if (!iter_bo) { /* Remove the buffer from the hash tables. */ handle_table_remove(&dev->bo_handles, bo->handle); diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c index 8a99b8bb..1709099e 100644 --- a/amdgpu/amdgpu_device.c +++ b/amdgpu/amdgpu_device.c @@ -72,9 +72,6 @@ static int fd_compare(int fd1, int fd2) static void amdgpu_device_free(struct amdgpu_core_device *dev) { - if (--dev->refcount > 0) - return; - close(dev->fd); amdgpu_vamgr_deinit(&dev->vamgr_32); @@ -102,6 +99,26 @@ static bool same_file_description(int fd1, int fd2) return fd1 == fd2; } +static void amdgpu_device_unreference(amdgpu_device_handle user_dev) +{ + struct amdgpu_device *dev; + + if (!user_dev->core) + return; + + /* Are there any other user devices left referencing the core device? */ + for (dev = dev_list; dev; dev = dev->next) { + if (dev == user_dev) + continue; + + if (dev->core == user_dev->core) + break; + } + + if (!dev) + amdgpu_device_free(user_dev->core); +} + static int amdgpu_device_init(amdgpu_device_handle user_dev) { struct amdgpu_device *dev_iter; @@ -115,7 +132,6 @@ static int amdgpu_device_init(amdgpu_device_handle user_dev) break; if (dev_iter) { - dev_iter->core->refcount++; user_dev->core = dev_iter->core; return 0; } @@ -126,7 +142,6 @@ static int amdgpu_device_init(amdgpu_device_handle user_dev) return -ENOMEM; } - dev->refcount = 1; pthread_mutex_init(&dev->bo_table_mutex, NULL); dev->fd = user_dev->user_fd; @@ -251,8 +266,7 @@ out: cleanup: if (!user_dev->core || user_dev->user_fd != user_dev->core->fd) close(user_dev->user_fd); - if (user_dev->core) - amdgpu_device_free(user_dev->core); + amdgpu_device_unreference(user_dev); free(user_dev); pthread_mutex_unlock(&dev_mutex); return r; @@ -274,7 +288,7 @@ drm_public int amdgpu_device_deinitialize(amdgpu_device_handle user_dev) if (user_dev->user_fd != dev->fd) close(user_dev->user_fd); - amdgpu_device_free(dev); + amdgpu_device_unreference(user_dev); free(user_dev); } diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index 70566f98..7110e30c 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h @@ -65,7 +65,6 @@ struct amdgpu_va { }; struct amdgpu_core_device { - int refcount; int fd; unsigned major_version; unsigned minor_version; @@ -97,7 +96,6 @@ struct amdgpu_device { }; struct amdgpu_core_bo { - int refcount; amdgpu_bo_handle user_bos; uint64_t alloc_size; -- 2.20.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel