freedreno: re-work fd_batch_reference() locking
authorRob Clark <robdclark@gmail.com>
Tue, 17 Jul 2018 14:14:59 +0000 (10:14 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 17 Jul 2018 15:00:00 +0000 (11:00 -0400)
Annoyingly we still have to briefly drop the lock to unref resources..
but push the lock down into __fd_batch_destroy() so we can invalidate
the batch and reset resources before dropping the lock.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/freedreno_batch.c
src/gallium/drivers/freedreno/freedreno_batch.h

index 18e4ca5..84de03b 100644 (file)
@@ -223,24 +223,26 @@ fd_batch_reset(struct fd_batch *batch)
 void
 __fd_batch_destroy(struct fd_batch *batch)
 {
+       struct fd_context *ctx = batch->ctx;
+
        DBG("%p", batch);
 
-       util_copy_framebuffer_state(&batch->framebuffer, NULL);
+       fd_context_assert_locked(batch->ctx);
 
-       mtx_lock(&batch->ctx->screen->lock);
        fd_bc_invalidate_batch(batch, true);
-       mtx_unlock(&batch->ctx->screen->lock);
 
-       batch_fini(batch);
-
-       batch_reset_resources(batch);
+       batch_reset_resources_locked(batch);
        debug_assert(batch->resources->entries == 0);
        _mesa_set_destroy(batch->resources, NULL);
 
        batch_flush_reset_dependencies(batch, false);
        debug_assert(batch->dependents_mask == 0);
 
+       fd_context_unlock(ctx);
+       util_copy_framebuffer_state(&batch->framebuffer, NULL);
+       batch_fini(batch);
        free(batch);
+       fd_context_lock(ctx);
 }
 
 void
index 294eca8..4b0539d 100644 (file)
@@ -228,16 +228,6 @@ void __fd_batch_destroy(struct fd_batch *batch);
  * __fd_batch_destroy() needs to unref resources)
  */
 
-static inline void
-fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
-{
-       struct fd_batch *old_batch = *ptr;
-       if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
-                       (debug_reference_descriptor)__fd_batch_describe))
-               __fd_batch_destroy(old_batch);
-       *ptr = batch;
-}
-
 /* fwd-decl prototypes to untangle header dependency :-/ */
 static inline void fd_context_assert_locked(struct fd_context *ctx);
 static inline void fd_context_lock(struct fd_context *ctx);
@@ -248,21 +238,32 @@ fd_batch_reference_locked(struct fd_batch **ptr, struct fd_batch *batch)
 {
        struct fd_batch *old_batch = *ptr;
 
+       /* only need lock if a reference is dropped: */
        if (old_batch)
                fd_context_assert_locked(old_batch->ctx);
-       else if (batch)
-               fd_context_assert_locked(batch->ctx);
 
        if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
-                       (debug_reference_descriptor)__fd_batch_describe)) {
-               struct fd_context *ctx = old_batch->ctx;
-               fd_context_unlock(ctx);
+                       (debug_reference_descriptor)__fd_batch_describe))
                __fd_batch_destroy(old_batch);
-               fd_context_lock(ctx);
-       }
+
        *ptr = batch;
 }
 
+static inline void
+fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
+{
+       struct fd_batch *old_batch = *ptr;
+       struct fd_context *ctx = old_batch ? old_batch->ctx : NULL;
+
+       if (ctx)
+               fd_context_lock(ctx);
+
+       fd_batch_reference_locked(ptr, batch);
+
+       if (ctx)
+               fd_context_unlock(ctx);
+}
+
 #include "freedreno_context.h"
 
 static inline void