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>
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)