From f3fb1d663277f231f0d429c6bbb784461e26cb09 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 30 Apr 2022 10:22:31 -0700 Subject: [PATCH] drm-shim: Cleanup on device file close Avoid leaking memory when the device file is closed, dropping bo references and freeing the shim_fd. Signed-off-by: Rob Clark Reviewed-by: Emma Anholt Part-of: --- src/drm-shim/device.c | 21 ++++++++++++++++++++- src/drm-shim/drm_shim.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/drm-shim/device.c b/src/drm-shim/device.c index 9ec1f274ea5..6c9c994643b 100644 --- a/src/drm-shim/device.c +++ b/src/drm-shim/device.c @@ -117,6 +117,7 @@ drm_shim_file_create(int fd) struct shim_fd *shim_fd = calloc(1, sizeof(*shim_fd)); shim_fd->fd = fd; + p_atomic_set(&shim_fd->refcount, 1); mtx_init(&shim_fd->handle_lock, mtx_plain); shim_fd->handles = _mesa_hash_table_create(NULL, uint_key_hash, @@ -133,13 +134,31 @@ void drm_shim_fd_register(int fd, struct shim_fd *shim_fd) { if (!shim_fd) shim_fd = drm_shim_file_create(fd); + else + p_atomic_inc(&shim_fd->refcount); _mesa_hash_table_insert(shim_device.fd_map, (void *)(uintptr_t)(fd + 1), shim_fd); } +static void handle_delete_fxn(struct hash_entry *entry) +{ + drm_shim_bo_put(entry->data); +} + void drm_shim_fd_unregister(int fd) { - _mesa_hash_table_remove_key(shim_device.fd_map, (void *)(uintptr_t)(fd + 1)); + struct hash_entry *entry = + _mesa_hash_table_search(shim_device.fd_map, (void *)(uintptr_t)(fd + 1)); + if (!entry) + return; + struct shim_fd *shim_fd = entry->data; + _mesa_hash_table_remove(shim_device.fd_map, entry); + + if (!p_atomic_dec_zero(&shim_fd->refcount)) + return; + + _mesa_hash_table_destroy(shim_fd->handles, handle_delete_fxn); + free(shim_fd); } struct shim_fd * diff --git a/src/drm-shim/drm_shim.h b/src/drm-shim/drm_shim.h index 4eda0f15030..7b1bd72e70f 100644 --- a/src/drm-shim/drm_shim.h +++ b/src/drm-shim/drm_shim.h @@ -69,6 +69,7 @@ extern struct shim_device shim_device; struct shim_fd { int fd; + int refcount; mtx_t handle_lock; /* mapping from int gem handle to struct shim_bo *. */ struct hash_table *handles;