blob: 6783d4f7c9ca512652dba301ebd2535a2618df24 [file] [log] [blame]
From c54fb6ef3d81b5c1e88c6d4ae2ea5d534cb18c8c Mon Sep 17 00:00:00 2001
From: Lepton Wu <lepton@chromium.org>
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 <lepton@chromium.org>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9701>
---
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)
--
2.31.1.498.g6c1eba8ee3d-goog