From 4cf8f329edb3ad3482819de8dc091061ae19c5af Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 17 Jul 2018 10:14:59 -0400 Subject: [PATCH] freedreno: re-work fd_batch_reference() locking 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 --- .../drivers/freedreno/freedreno_batch.c | 14 ++++---- .../drivers/freedreno/freedreno_batch.h | 35 ++++++++++--------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c index 18e4ca5fb03..84de03bad32 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.c +++ b/src/gallium/drivers/freedreno/freedreno_batch.c @@ -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 diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index 294eca8f531..4b0539d0062 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -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 -- 2.30.2