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

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Oct 19 20:59:46 UTC 2021


Module: Mesa
Branch: staging/21.3
Commit: 6154aee4b9c6b6b0b5768ab5f338732940bd485e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6154aee4b9c6b6b0b5768ab5f338732940bd485e

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>
(cherry picked from commit 86b3d8c66ce17ddcaefa5bdea68882cc03a57f15)

---

 .pick_status.json                       | 2 +-
 src/gallium/drivers/zink/zink_context.c | 5 +++++
 src/gallium/drivers/zink/zink_surface.c | 5 +++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/.pick_status.json b/.pick_status.json
index 00a551de6ec..2505134e7b0 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -4,7 +4,7 @@
         "description": "zink: rescue surfaces/bufferviews for cache hits during deletion",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 58fbc220624..56211a4d0ee 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