From c54fb6ef3d81b5c1e88c6d4ae2ea5d534cb18c8c Mon Sep 17 00:00:00 2001 From: Lepton Wu Date: Thu, 18 Mar 2021 23:05:19 -0700 Subject: [PATCH] virgl: Don't destroy resource while it's in use. This is the race condition: thread 1 check reference count of resource and then find out out it's zero and then it begin to destroy it. Around the same time, thread 2 gets the lock and get the resource from the hash table and plan to use it. Then this resource gets destroyed while it's still in use. Signed-off-by: Lepton Wu Reviewed-by: Chia-I Wu Part-of: --- src/gallium/winsys/virgl/drm/virgl_drm_winsys.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index f0e95eff8a6..0031db7d278 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -72,6 +72,16 @@ static void virgl_hw_res_destroy(struct virgl_drm_winsys *qdws, struct drm_gem_close args; mtx_lock(&qdws->bo_handles_mutex); + + /* We intentionally avoid taking the lock in + * virgl_drm_resource_reference. Now that the + * lock is taken, we need to check the refcount + * again. */ + if (pipe_is_referenced(&res->reference)) { + mtx_unlock(&qdws->bo_handles_mutex); + return; + } + _mesa_hash_table_remove_key(qdws->bo_handles, (void *)(uintptr_t)res->bo_handle); if (res->flink_name)