virgl: Don't destroy resource while it's in use.
authorLepton Wu <lepton@chromium.org>
Fri, 19 Mar 2021 06:05:19 +0000 (23:05 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 19 Mar 2021 18:58:01 +0000 (18:58 +0000)
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

index f0e95ef..0031db7 100644 (file)
@@ -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)