mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 11:28:05 +02:00
freedreno/drm/virtio: Drop blocking in host
These paths should be corner cases, but still it is a bad idea to block in the host (because it is single threaded), so instead just turn waits in the host into polling in the guest. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16086>
This commit is contained in:
parent
e6b2785811
commit
441f01e778
3 changed files with 27 additions and 32 deletions
|
|
@ -184,22 +184,15 @@ struct msm_ccmd_gem_info_rsp {
|
||||||
*
|
*
|
||||||
* Maps to DRM_MSM_GEM_CPU_PREP
|
* Maps to DRM_MSM_GEM_CPU_PREP
|
||||||
*
|
*
|
||||||
* Note: currently this uses a relative timeout mapped to absolute timeout
|
* Note: Since we don't want to block the single threaded host, this returns
|
||||||
* on the host, because I don't think we can rely on monotonic time being
|
* immediately with -EBUSY if the fence is not yet signaled. The guest
|
||||||
* aligned between host and guest. This has the slight drawback of not
|
* should poll if needed.
|
||||||
* handling interrupted syscalls on the guest side, but since the actual
|
|
||||||
* waiting happens on the host side (after guest execbuf ioctl returns)
|
|
||||||
* this shouldn't be *that* much of a problem.
|
|
||||||
*
|
|
||||||
* If we could rely on host and guest times being aligned, we could use
|
|
||||||
* MSM_CCMD_IOCTL_SIMPLE instead
|
|
||||||
*/
|
*/
|
||||||
struct msm_ccmd_gem_cpu_prep_req {
|
struct msm_ccmd_gem_cpu_prep_req {
|
||||||
struct msm_ccmd_req hdr;
|
struct msm_ccmd_req hdr;
|
||||||
|
|
||||||
uint32_t host_handle;
|
uint32_t host_handle;
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
uint64_t timeout;
|
|
||||||
};
|
};
|
||||||
DEFINE_CAST(msm_ccmd_req, msm_ccmd_gem_cpu_prep_req)
|
DEFINE_CAST(msm_ccmd_req, msm_ccmd_gem_cpu_prep_req)
|
||||||
|
|
||||||
|
|
@ -326,22 +319,15 @@ struct msm_ccmd_submitqueue_query_rsp {
|
||||||
*
|
*
|
||||||
* Maps to DRM_MSM_WAIT_FENCE
|
* Maps to DRM_MSM_WAIT_FENCE
|
||||||
*
|
*
|
||||||
* Note: currently this uses a relative timeout mapped to absolute timeout
|
* Note: Since we don't want to block the single threaded host, this returns
|
||||||
* on the host, because I don't think we can rely on monotonic time being
|
* immediately with -ETIMEDOUT if the fence is not yet signaled. The guest
|
||||||
* aligned between host and guest. This has the slight drawback of not
|
* should poll if needed.
|
||||||
* handling interrupted syscalls on the guest side, but since the actual
|
|
||||||
* waiting happens on the host side (after guest execbuf ioctl returns)
|
|
||||||
* this shouldn't be *that* much of a problem.
|
|
||||||
*
|
|
||||||
* If we could rely on host and guest times being aligned, we could use
|
|
||||||
* MSM_CCMD_IOCTL_SIMPLE instead
|
|
||||||
*/
|
*/
|
||||||
struct msm_ccmd_wait_fence_req {
|
struct msm_ccmd_wait_fence_req {
|
||||||
struct msm_ccmd_req hdr;
|
struct msm_ccmd_req hdr;
|
||||||
|
|
||||||
uint32_t queue_id;
|
uint32_t queue_id;
|
||||||
uint32_t fence;
|
uint32_t fence;
|
||||||
uint64_t timeout;
|
|
||||||
};
|
};
|
||||||
DEFINE_CAST(msm_ccmd_req, msm_ccmd_wait_fence_req)
|
DEFINE_CAST(msm_ccmd_req, msm_ccmd_wait_fence_req)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,17 +106,19 @@ virtio_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
|
||||||
.hdr = MSM_CCMD(GEM_CPU_PREP, sizeof(req)),
|
.hdr = MSM_CCMD(GEM_CPU_PREP, sizeof(req)),
|
||||||
.host_handle = virtio_bo_host_handle(bo),
|
.host_handle = virtio_bo_host_handle(bo),
|
||||||
.op = op,
|
.op = op,
|
||||||
.timeout = 5000000000,
|
|
||||||
};
|
};
|
||||||
struct msm_ccmd_gem_cpu_prep_rsp *rsp;
|
struct msm_ccmd_gem_cpu_prep_rsp *rsp;
|
||||||
|
|
||||||
rsp = virtio_alloc_rsp(bo->dev, &req.hdr, sizeof(*rsp));
|
/* We can't do a blocking wait in the host, so we have to poll: */
|
||||||
|
do {
|
||||||
|
rsp = virtio_alloc_rsp(bo->dev, &req.hdr, sizeof(*rsp));
|
||||||
|
|
||||||
ret = virtio_execbuf(bo->dev, &req.hdr, true);
|
ret = virtio_execbuf(bo->dev, &req.hdr, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = rsp->ret;
|
ret = rsp->ret;
|
||||||
|
} while (ret == -EBUSY);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -115,17 +115,24 @@ virtio_pipe_wait(struct fd_pipe *pipe, const struct fd_fence *fence, uint64_t ti
|
||||||
.hdr = MSM_CCMD(WAIT_FENCE, sizeof(req)),
|
.hdr = MSM_CCMD(WAIT_FENCE, sizeof(req)),
|
||||||
.queue_id = to_virtio_pipe(pipe)->queue_id,
|
.queue_id = to_virtio_pipe(pipe)->queue_id,
|
||||||
.fence = fence->kfence,
|
.fence = fence->kfence,
|
||||||
.timeout = timeout,
|
|
||||||
};
|
};
|
||||||
struct msm_ccmd_submitqueue_query_rsp *rsp;
|
struct msm_ccmd_submitqueue_query_rsp *rsp;
|
||||||
|
int64_t end_time = os_time_get_nano() + timeout;
|
||||||
|
int ret;
|
||||||
|
|
||||||
rsp = virtio_alloc_rsp(pipe->dev, &req.hdr, sizeof(*rsp));
|
do {
|
||||||
|
rsp = virtio_alloc_rsp(pipe->dev, &req.hdr, sizeof(*rsp));
|
||||||
|
|
||||||
int ret = virtio_execbuf(pipe->dev, &req.hdr, true);
|
ret = virtio_execbuf(pipe->dev, &req.hdr, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = rsp->ret;
|
if ((timeout != PIPE_TIMEOUT_INFINITE) &&
|
||||||
|
(os_time_get_nano() >= end_time))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = rsp->ret;
|
||||||
|
} while (ret == -ETIMEDOUT);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue