Mesa (main): zink: rescue surfaces/bufferviews for cache hits during deletion

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Oct 19 19:57:50 UTC 2021


Module: Mesa
Branch: main
Commit: 86b3d8c66ce17ddcaefa5bdea68882cc03a57f15
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=86b3d8c66ce17ddcaefa5bdea68882cc03a57f15

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue Oct 19 13:57:39 2021 -0400

zink: rescue surfaces/bufferviews for cache hits during deletion

this is a wild race condition, but it's possible for these to get their
final unref, enter their destructor, and then get a cache hit while waiting
on the lock to remove themselves from the cache

in such a scenario, a second, normal check of the refcount will suffice,
as the increment is atomic, and the value will otherwise be zero

fixes crashes in basemark

cc: mesa-stable

Reviewed-by: Hoe Hao Cheng <haochengho12907 at gmail.com>
Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13442>

---

 src/gallium/drivers/zink/zink_context.c | 5 +++++
 src/gallium/drivers/zink/zink_surface.c | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 7083d2835aa..0ecfd8540db 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -777,6 +777,11 @@ zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *bu
 {
    struct zink_resource *res = zink_resource(buffer_view->pres);
    simple_mtx_lock(&res->bufferview_mtx);
+   if (buffer_view->reference.count) {
+      /* got a cache hit during deletion */
+      simple_mtx_unlock(&res->bufferview_mtx);
+      return;
+   }
    struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->bufferview_cache, buffer_view->hash, &buffer_view->bvci);
    assert(he);
    _mesa_hash_table_remove(&res->bufferview_cache, he);
diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c
index 08dc0057ffa..e7af9963529 100644
--- a/src/gallium/drivers/zink/zink_surface.c
+++ b/src/gallium/drivers/zink/zink_surface.c
@@ -281,6 +281,11 @@ zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface)
    struct zink_resource *res = zink_resource(psurface->texture);
    if (!psurface->nr_samples) {
       simple_mtx_lock(&res->surface_mtx);
+      if (psurface->reference.count) {
+         /* got a cache hit during deletion */
+         simple_mtx_unlock(&res->surface_mtx);
+         return;
+      }
       struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->surface_cache, surface->hash, &surface->ivci);
       assert(he);
       assert(he->data == surface);



More information about the mesa-commit mailing list