diff options
author | Yiwei Zhang <zzyiwei@chromium.org> | 2022-04-13 08:13:47 +0000 |
---|---|---|
committer | Yiwei Zhang <zzyiwei@chromium.org> | 2022-04-13 08:13:47 +0000 |
commit | f1fc252aec3b575775ce7f64cc9b9c1e708564f1 (patch) | |
tree | 6e8a2b3759089e3cf8ab422c312ad73fd4b29110 | |
parent | f77dd9aefb83cf90208b46c0a03804f1e62f0033 (diff) | |
download | virglrenderer-f1fc252aec3b575775ce7f64cc9b9c1e708564f1.tar.gz |
proxy: ensure fence added to timeline before retired with async_cb
For cpu syncs, with async_cb, fence_retire gets called inside
render worker submit_fence. Sync thread of proxy will catch is right
away. Without this CL, the guest cpu syncs will always wait until
timeout.
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/783>
-rw-r--r-- | src/proxy/proxy_context.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/src/proxy/proxy_context.c b/src/proxy/proxy_context.c index b5d15ca3..509c0b16 100644 --- a/src/proxy/proxy_context.c +++ b/src/proxy/proxy_context.c @@ -200,44 +200,53 @@ proxy_context_submit_fence(struct virgl_context *base, void *fence_cookie) { struct proxy_context *ctx = (struct proxy_context *)base; + const uint64_t old_busy_mask = ctx->timeline_busy_mask; /* TODO fix virglrenderer to match virtio-gpu spec which uses ring_idx */ const uint32_t ring_idx = queue_id; if (ring_idx >= PROXY_CONTEXT_TIMELINE_COUNT) return -EINVAL; + struct proxy_timeline *timeline = &ctx->timelines[ring_idx]; struct proxy_fence *fence = proxy_context_alloc_fence(ctx); if (!fence) return -ENOMEM; - struct proxy_timeline *timeline = &ctx->timelines[ring_idx]; - const uint32_t seqno = timeline->next_seqno++; + fence->flags = flags; + fence->seqno = timeline->next_seqno++; + fence->cookie = fence_cookie; + + if (proxy_renderer.flags & VIRGL_RENDERER_ASYNC_FENCE_CB) + mtx_lock(&ctx->timeline_mutex); + + list_addtail(&fence->head, &timeline->fences); + ctx->timeline_busy_mask |= 1 << ring_idx; + + if (proxy_renderer.flags & VIRGL_RENDERER_ASYNC_FENCE_CB) + mtx_unlock(&ctx->timeline_mutex); + const struct render_context_op_submit_fence_request req = { .header.op = RENDER_CONTEXT_OP_SUBMIT_FENCE, .flags = flags, .ring_index = ring_idx, - .seqno = seqno, + .seqno = fence->seqno, }; - if (!proxy_socket_send_request(&ctx->socket, &req, sizeof(req))) { - proxy_log("failed to submit fence"); - proxy_context_free_fence(ctx, fence); - return -1; - } - - fence->flags = flags; - fence->seqno = seqno; - fence->cookie = fence_cookie; + if (proxy_socket_send_request(&ctx->socket, &req, sizeof(req))) + return 0; + /* recover timeline fences and busy_mask on submit_fence request failure */ if (proxy_renderer.flags & VIRGL_RENDERER_ASYNC_FENCE_CB) mtx_lock(&ctx->timeline_mutex); - list_addtail(&fence->head, &timeline->fences); - ctx->timeline_busy_mask |= 1 << ring_idx; + list_del(&fence->head); + ctx->timeline_busy_mask = old_busy_mask; if (proxy_renderer.flags & VIRGL_RENDERER_ASYNC_FENCE_CB) mtx_unlock(&ctx->timeline_mutex); - return 0; + proxy_context_free_fence(ctx, fence); + proxy_log("failed to submit fence"); + return -1; } static void |