aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYiwei Zhang <zzyiwei@chromium.org>2022-04-13 08:13:47 +0000
committerYiwei Zhang <zzyiwei@chromium.org>2022-04-13 08:13:47 +0000
commitf1fc252aec3b575775ce7f64cc9b9c1e708564f1 (patch)
tree6e8a2b3759089e3cf8ab422c312ad73fd4b29110
parentf77dd9aefb83cf90208b46c0a03804f1e62f0033 (diff)
downloadvirglrenderer-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.c39
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