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

Author: Mike Blumenkrantz <[email protected]>
Date:   Fri Mar 10 12:48:30 2023 -0500

zink: track tc fences better

tc fence lifetimes can exceed the lifetimes of their parent contexts,
which means they can be destroyed after mfence->fence has been destroyed

to avoid invalid memory access on a destroyed fence, store all the assigned
tc fences into an array on the real fence and then use that to unset fence
pointers on any outstanding tc fences

fixes flakiness in 
dEQP-EGL.functional.sharing.gles2.multithread.random_egl_sync.images.texsubimage2d.12

in caselist:
dEQP-EGL.functional.query_context.get_current_surface.rgba4444_pbuffer
dEQP-EGL.functional.create_surface.platform_window.rgba5551_depth_no_stencil
dEQP-EGL.functional.query_surface.simple.pbuffer.rgb888_depth_no_stencil
dEQP-EGL.functional.color_clears.multi_context.gles2.rgb888_pixmap
dEQP-EGL.functional.color_clears.multi_context.gles1_gles2.rgba8888_window
dEQP-EGL.functional.color_clears.multi_context.gles1_gles2_gles3.rgb888_window
dEQP-EGL.functional.render.multi_thread.gles2_gles3.rgba5551_pbuffer
dEQP-EGL.functional.sharing.gles2.multithread.random_egl_sync.buffers.buffersubdata.3
dEQP-EGL.functional.sharing.gles2.multithread.random_egl_sync.programs.link.6
dEQP-EGL.functional.sharing.gles2.multithread.random_egl_sync.images.texsubimage2d.12

cc: mesa-stable

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21843>

---

 src/gallium/drivers/zink/zink_batch.c   | 7 +++++++
 src/gallium/drivers/zink/zink_context.c | 5 ++++-
 src/gallium/drivers/zink/zink_fence.c   | 2 ++
 src/gallium/drivers/zink/zink_types.h   | 1 +
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/zink/zink_batch.c 
b/src/gallium/drivers/zink/zink_batch.c
index e244a5fb4d7..435e6333adf 100644
--- a/src/gallium/drivers/zink/zink_batch.c
+++ b/src/gallium/drivers/zink/zink_batch.c
@@ -270,6 +270,12 @@ zink_batch_state_destroy(struct zink_screen *screen, 
struct zink_batch_state *bs
    util_dynarray_fini(&bs->bindless_releases[1]);
    util_dynarray_fini(&bs->acquires);
    util_dynarray_fini(&bs->acquire_flags);
+   unsigned num_mfences = util_dynarray_num_elements(&bs->fence.mfences, void 
*);
+   struct zink_tc_fence **mfence = bs->fence.mfences.data;
+   for (unsigned i = 0; i < num_mfences; i++) {
+      mfence[i]->fence = NULL;
+   }
+   util_dynarray_fini(&bs->fence.mfences);
    zink_batch_descriptor_deinit(screen, bs);
    ralloc_free(bs);
 }
@@ -326,6 +332,7 @@ create_batch_state(struct zink_context *ctx)
    util_dynarray_init(&bs->bindless_releases[0], NULL);
    util_dynarray_init(&bs->bindless_releases[1], NULL);
    util_dynarray_init(&bs->swapchain_obj, NULL);
+   util_dynarray_init(&bs->fence.mfences, NULL);
 
    cnd_init(&bs->usage.flush);
    mtx_init(&bs->usage.mtx, mtx_plain);
diff --git a/src/gallium/drivers/zink/zink_context.c 
b/src/gallium/drivers/zink/zink_context.c
index c181f225f1c..8119afd20cc 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -4146,10 +4146,13 @@ zink_flush(struct pipe_context *pctx,
          *pfence = (struct pipe_fence_handle *)mfence;
       }
 
+      assert(!mfence->fence);
       mfence->fence = fence;
       mfence->sem = export_sem;
-      if (fence)
+      if (fence) {
          mfence->submit_count = submit_count;
+         util_dynarray_append(&fence->mfences, struct zink_tc_fence *, mfence);
+      }
 
       if (deferred_fence) {
          assert(fence);
diff --git a/src/gallium/drivers/zink/zink_fence.c 
b/src/gallium/drivers/zink/zink_fence.c
index ee1101fb516..e46e09108d5 100644
--- a/src/gallium/drivers/zink/zink_fence.c
+++ b/src/gallium/drivers/zink/zink_fence.c
@@ -40,6 +40,8 @@
 static void
 destroy_fence(struct zink_screen *screen, struct zink_tc_fence *mfence)
 {
+   if (mfence->fence)
+      util_dynarray_delete_unordered(&mfence->fence->mfences, struct 
zink_tc_fence *, mfence);
    mfence->fence = NULL;
    tc_unflushed_batch_token_reference(&mfence->tc_token, NULL);
    if (mfence->sem)
diff --git a/src/gallium/drivers/zink/zink_types.h 
b/src/gallium/drivers/zink/zink_types.h
index 4f5251c45a0..e13984dfbca 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -246,6 +246,7 @@ struct zink_fence {
    uint64_t batch_id;
    bool submitted;
    bool completed;
+   struct util_dynarray mfences;
 };
 
 

Reply via email to