From 8357ef588f08c71bb3b4958e9764eb699452f3a7 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 27 Dec 2024 14:14:23 +0100 Subject: [PATCH] frontends/va: Unlock driver mutex for SyncSurface/Buffer fence wait Only keep context mutex locked while waiting for fence. This fixes issue with multi-threaded use of VAAPI where SyncSurface and SyncBuffer would block all contexts, even those used in different threads. The issue exists for all API calls, however in most cases this is not a big deal as most calls will return fast, but sync is expected to take up to tens of ms. Reviewed-by: Ruijing Dong Part-of: --- src/gallium/frontends/va/buffer.c | 14 +++++--------- src/gallium/frontends/va/surface.c | 19 +++++-------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/gallium/frontends/va/buffer.c b/src/gallium/frontends/va/buffer.c index 788834200ac..b5a199cfa42 100644 --- a/src/gallium/frontends/va/buffer.c +++ b/src/gallium/frontends/va/buffer.c @@ -555,31 +555,27 @@ vlVaSyncBuffer(VADriverContextP ctx, VABufferID buf_id, uint64_t timeout_ns) mtx_lock(&drv->mutex); buf = handle_table_get(drv->htab, buf_id); - if (!buf) { mtx_unlock(&drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; } + /* No outstanding operation: nothing to do. */ if (!buf->fence) { - /* No outstanding operation: nothing to do. */ mtx_unlock(&drv->mutex); return VA_STATUS_SUCCESS; } context = buf->ctx; - if (!context) { + if (!context || !context->decoder) { mtx_unlock(&drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; } - if (!context->decoder) { - mtx_unlock(&drv->mutex); - return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - } - - int ret = context->decoder->fence_wait(context->decoder, buf->fence, timeout_ns); + mtx_lock(&context->mutex); mtx_unlock(&drv->mutex); + int ret = context->decoder->fence_wait(context->decoder, buf->fence, timeout_ns); + mtx_unlock(&context->mutex); return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT; } #endif diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index f93e4f0660c..a5220049452 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -187,30 +187,21 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo pscreen->fence_reference(pscreen, &surf->pipe_fence, NULL); } - /* This is checked before getting the context below as - * surf->ctx is only set in begin_frame - * and not when the surface is created - * Some apps try to sync/map the surface right after creation and - * would get VA_STATUS_ERROR_INVALID_CONTEXT - */ + /* No outstanding operation: nothing to do. */ if (!surf->fence) { - // No outstanding encode/decode operation: nothing to do. mtx_unlock(&drv->mutex); return VA_STATUS_SUCCESS; } - if (!context) { + if (!context || !context->decoder) { mtx_unlock(&drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; } - if (!context->decoder) { - mtx_unlock(&drv->mutex); - return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - } - - int ret = context->decoder->fence_wait(context->decoder, fence, timeout_ns); + mtx_lock(&context->mutex); mtx_unlock(&drv->mutex); + int ret = context->decoder->fence_wait(context->decoder, fence, timeout_ns); + mtx_unlock(&context->mutex); return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT; }