Mesa (main): radeonsi: use helpers to access si_screen::aux_context

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 15 11:02:19 UTC 2022


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

Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date:   Tue Jun 14 16:37:20 2022 +0200

radeonsi: use helpers to access si_screen::aux_context

This avoids to mistakenly use the context without locking it first.

The aux_context_lock needs to become a recursive one now, since
si_texture_get_handle can call si_reallocate_texture_inplace which
uses resource_create which may use the aux_context too.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6666
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17032>

---

 src/gallium/drivers/radeonsi/si_compute_blit.c |  7 ++--
 src/gallium/drivers/radeonsi/si_pipe.c         | 44 ++++++++++++++------------
 src/gallium/drivers/radeonsi/si_pipe.h         |  7 ++--
 src/gallium/drivers/radeonsi/si_texture.c      | 41 ++++++++++--------------
 4 files changed, 45 insertions(+), 54 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c
index 9a800adb3b5..5cdb48346da 100644
--- a/src/gallium/drivers/radeonsi/si_compute_blit.c
+++ b/src/gallium/drivers/radeonsi/si_compute_blit.c
@@ -434,13 +434,10 @@ void si_clear_buffer(struct si_context *sctx, struct pipe_resource *dst,
 void si_screen_clear_buffer(struct si_screen *sscreen, struct pipe_resource *dst, uint64_t offset,
                             uint64_t size, unsigned value, unsigned flags)
 {
-   struct si_context *ctx = (struct si_context *)sscreen->aux_context;
-
-   simple_mtx_lock(&sscreen->aux_context_lock);
+   struct si_context *ctx = si_get_aux_context(sscreen);
    si_clear_buffer(ctx, dst, offset, size, &value, 4, flags,
                    SI_COHERENCY_SHADER, SI_AUTO_SELECT_CLEAR_METHOD);
-   sscreen->aux_context->flush(sscreen->aux_context, NULL, 0);
-   simple_mtx_unlock(&sscreen->aux_context_lock);
+   si_put_aux_context_flush(sscreen);
 }
 
 static void si_pipe_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 08a4482dbcb..7ab529f76a5 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -795,24 +795,24 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign
       p_atomic_inc(&screen->num_contexts);
 
       /* Check if the aux_context needs to be recreated */
-      struct si_context *saux = (struct si_context *)sscreen->aux_context;
+      struct si_context *saux = si_get_aux_context(sscreen);
 
-      simple_mtx_lock(&sscreen->aux_context_lock);
       enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(
          saux->ctx, true, NULL);
       if (status != PIPE_NO_RESET) {
          /* We lost the aux_context, create a new one */
          struct u_log_context *aux_log = (saux)->log;
-         sscreen->aux_context->set_log_context(sscreen->aux_context, NULL);
-         sscreen->aux_context->destroy(sscreen->aux_context);
+         saux->b.set_log_context(&saux->b, NULL);
+         saux->b.destroy(&saux->b);
 
-         sscreen->aux_context = si_create_context(
+         saux = (struct si_context *)si_create_context(
             &sscreen->b, SI_CONTEXT_FLAG_AUX |
                          (sscreen->options.aux_debug ? PIPE_CONTEXT_DEBUG : 0) |
                          (sscreen->info.has_graphics ? 0 : PIPE_CONTEXT_COMPUTE_ONLY));
-         sscreen->aux_context->set_log_context(sscreen->aux_context, aux_log);
+         saux->b.set_log_context(&saux->b, aux_log);
+         sscreen->aux_context = saux;
       }
-      simple_mtx_unlock(&sscreen->aux_context_lock);
+      si_put_aux_context_flush(sscreen);
 
       simple_mtx_lock(&sscreen->async_compute_context_lock);
       if (status != PIPE_NO_RESET && sscreen->async_compute_context) {
@@ -920,18 +920,19 @@ static void si_destroy_screen(struct pipe_screen *pscreen)
 
    si_resource_reference(&sscreen->attribute_ring, NULL);
 
-   simple_mtx_destroy(&sscreen->aux_context_lock);
-
    if (sscreen->aux_context) {
-       struct u_log_context *aux_log = ((struct si_context *)sscreen->aux_context)->log;
-       if (aux_log) {
-          sscreen->aux_context->set_log_context(sscreen->aux_context, NULL);
-          u_log_context_destroy(aux_log);
-          FREE(aux_log);
-       }
-
-       sscreen->aux_context->destroy(sscreen->aux_context);
+      struct si_context *saux = si_get_aux_context(sscreen);
+      struct u_log_context *aux_log = saux->log;
+      if (aux_log) {
+         saux->b.set_log_context(&saux->b, NULL);
+         u_log_context_destroy(aux_log);
+         FREE(aux_log);
+      }
+
+      saux->b.destroy(&saux->b);
+      mtx_unlock(&sscreen->aux_context_lock);
    }
+   mtx_destroy(&sscreen->aux_context_lock);
 
    simple_mtx_destroy(&sscreen->async_compute_context_lock);
    if (sscreen->async_compute_context) {
@@ -1187,7 +1188,7 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws,
              1 << util_logbase2(sscreen->force_aniso));
    }
 
-   (void)simple_mtx_init(&sscreen->aux_context_lock, mtx_plain);
+   (void)mtx_init(&sscreen->aux_context_lock, mtx_recursive);
    (void)simple_mtx_init(&sscreen->async_compute_context_lock, mtx_plain);
    (void)simple_mtx_init(&sscreen->gpu_load_mutex, mtx_plain);
    (void)simple_mtx_init(&sscreen->gds_mutex, mtx_plain);
@@ -1418,7 +1419,8 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws,
    if (sscreen->options.aux_debug) {
       struct u_log_context *log = CALLOC_STRUCT(u_log_context);
       u_log_context_init(log);
-      sscreen->aux_context->set_log_context(sscreen->aux_context, log);
+      si_get_aux_context(sscreen)->b.set_log_context(sscreen->aux_context, log);
+      si_put_aux_context_flush(sscreen);
    }
 
    if (test_flags & DBG(TEST_IMAGE_COPY))
@@ -1472,7 +1474,7 @@ struct pipe_screen *radeonsi_screen_create(int fd, const struct pipe_screen_conf
 
 struct si_context* si_get_aux_context(struct si_screen *sscreen)
 {
-   simple_mtx_lock(&sscreen->aux_context_lock);
+   mtx_lock(&sscreen->aux_context_lock);
    return (struct si_context*)sscreen->aux_context;
 }
 
@@ -1480,5 +1482,5 @@ void si_put_aux_context_flush(struct si_screen *sscreen)
 {
    struct pipe_context *c = &((struct si_context*)sscreen->aux_context)->b;
    c->flush(c, NULL, 0);
-   simple_mtx_unlock(&sscreen->aux_context_lock);
+   mtx_unlock(&sscreen->aux_context_lock);
 }
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 315a179f977..6cd7466baa5 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -606,10 +606,9 @@ struct si_screen {
 
    unsigned max_texel_buffer_elements;
 
-   /* Auxiliary context. Mainly used to initialize resources.
-    * It must be locked prior to using and flushed before unlocking. */
-   struct pipe_context *aux_context;
-   simple_mtx_t aux_context_lock;
+   /* Auxiliary context. Mainly used to initialize resources. */
+   void *aux_context;
+   mtx_t aux_context_lock;
 
    /* Async compute context for DRI_PRIME copies. */
    struct pipe_context *async_compute_context;
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 4dceda3d615..88698e5b6cc 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -314,12 +314,8 @@ static int si_init_surface(struct si_screen *sscreen, struct radeon_surf *surfac
 void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *tex,
                                    bool *ctx_flushed)
 {
-   struct si_screen *sscreen = sctx->screen;
    struct pipe_context *ctx = &sctx->b;
 
-   if (ctx == sscreen->aux_context)
-      simple_mtx_lock(&sscreen->aux_context_lock);
-
    unsigned n = sctx->num_decompress_calls;
    ctx->flush_resource(ctx, &tex->buffer.b.b);
 
@@ -332,9 +328,6 @@ void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *t
    }
    if (ctx_flushed)
       *ctx_flushed = flushed;
-
-   if (ctx == sscreen->aux_context)
-      simple_mtx_unlock(&sscreen->aux_context_lock);
 }
 
 void si_texture_discard_cmask(struct si_screen *sscreen, struct si_texture *tex)
@@ -414,16 +407,10 @@ bool si_texture_disable_dcc(struct si_context *sctx, struct si_texture *tex)
    if (!si_can_disable_dcc(tex))
       return false;
 
-   if (&sctx->b == sscreen->aux_context)
-      simple_mtx_lock(&sscreen->aux_context_lock);
-
    /* Decompress DCC. */
    si_decompress_dcc(sctx, tex);
    sctx->b.flush(&sctx->b, NULL, 0);
 
-   if (&sctx->b == sscreen->aux_context)
-      simple_mtx_unlock(&sscreen->aux_context_lock);
-
    return si_texture_discard_dcc(sscreen, tex);
 }
 
@@ -671,7 +658,7 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
    bool flush = false;
 
    ctx = threaded_context_unwrap_sync(ctx);
-   sctx = (struct si_context *)(ctx ? ctx : sscreen->aux_context);
+   sctx = ctx ? (struct si_context *)ctx : si_get_aux_context(sscreen);
 
    if (resource->target != PIPE_BUFFER) {
       unsigned plane = whandle->plane;
@@ -688,12 +675,17 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
       /* This is not supported now, but it might be required for OpenCL
        * interop in the future.
        */
-      if (resource->nr_samples > 1 || tex->is_depth)
+      if (resource->nr_samples > 1 || tex->is_depth) {
+         if (!ctx)
+            si_put_aux_context_flush(sscreen);
          return false;
+      }
 
       whandle->size = tex->buffer.bo_size;
 
       if (plane) {
+         if (!ctx)
+            si_put_aux_context_flush(sscreen);
          whandle->offset = ac_surface_get_plane_offset(sscreen->info.gfx_level,
                                                        &tex->surface, plane, 0);
          whandle->stride = ac_surface_get_plane_stride(sscreen->info.gfx_level,
@@ -737,8 +729,7 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
          bool flushed;
          si_eliminate_fast_color_clear(sctx, tex, &flushed);
          /* eliminate_fast_color_clear sometimes flushes the context */
-         if (flushed)
-            flush = false;
+         flush = !flushed;
 
          /* Disable CMASK if flush_resource isn't going
           * to be called.
@@ -774,8 +765,11 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
          templ.bind |= PIPE_BIND_SHARED;
 
          struct pipe_resource *newb = screen->resource_create(screen, &templ);
-         if (!newb)
+         if (!newb) {
+            if (!ctx)
+               si_put_aux_context_flush(sscreen);
             return false;
+         }
 
          /* Copy the old buffer contents to the new one. */
          struct pipe_box box;
@@ -808,8 +802,10 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
       res->external_usage = usage;
    }
 
-   if (flush)
+   if (flush && ctx)
       sctx->b.flush(&sctx->b, NULL, 0);
+   if (!ctx)
+      si_put_aux_context_flush(sscreen);
 
    whandle->stride = stride;
    whandle->offset = offset + slice_size * whandle->layer;
@@ -1133,11 +1129,8 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
 
    /* Execute the clears. */
    if (num_clears) {
-      simple_mtx_lock(&sscreen->aux_context_lock);
-      si_execute_clears((struct si_context *)sscreen->aux_context,
-                        clears, num_clears, 0);
-      sscreen->aux_context->flush(sscreen->aux_context, NULL, 0);
-      simple_mtx_unlock(&sscreen->aux_context_lock);
+      si_execute_clears(si_get_aux_context(sscreen), clears, num_clears, 0);
+      si_put_aux_context_flush(sscreen);
    }
 
    /* Initialize the CMASK base register value. */



More information about the mesa-commit mailing list