From 528fa581c1f74a0abbb63a11faed8dea7a3d7af7 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 12 Apr 2022 14:09:03 -0700 Subject: [PATCH] freedreno/drm/virtio: Pass guest handles to execbuf This is needed for the VIRTGPU_WAIT ioctl to work. TODO we could perhaps limit this, since it is not needed for residency, but only fencing. Ie. we could omit cmdstream, and probably anything that has FD_BO_NOMAP flag. Signed-off-by: Rob Clark Part-of: --- src/freedreno/drm/virtio/virtio_device.c | 6 +++++- src/freedreno/drm/virtio/virtio_priv.h | 1 + src/freedreno/drm/virtio/virtio_ringbuffer.c | 13 +++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/freedreno/drm/virtio/virtio_device.c b/src/freedreno/drm/virtio/virtio_device.c index 891deda2268..dddabe76a49 100644 --- a/src/freedreno/drm/virtio/virtio_device.c +++ b/src/freedreno/drm/virtio/virtio_device.c @@ -248,6 +248,7 @@ virtio_alloc_rsp(struct fd_device *dev, struct msm_ccmd_req *req, uint32_t sz) */ int virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req, + uint32_t *handles, uint32_t num_handles, int in_fence_fd, int *out_fence_fd, int ring_idx) { struct virtio_device *virtio_dev = to_virtio_device(dev); @@ -264,6 +265,8 @@ virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req, .size = req->len, .command = VOID2U64(req), .ring_idx = ring_idx, + .bo_handles = VOID2U64(handles), + .num_bo_handles = num_handles, }; int ret = drmIoctl(dev->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &eb); @@ -283,7 +286,8 @@ int virtio_execbuf(struct fd_device *dev, struct msm_ccmd_req *req, bool sync) { int fence_fd; - int ret = virtio_execbuf_fenced(dev, req, -1, sync ? &fence_fd : NULL, 0); + int ret = virtio_execbuf_fenced(dev, req, NULL, 0, -1, + sync ? &fence_fd : NULL, 0); if (ret) return ret; diff --git a/src/freedreno/drm/virtio/virtio_priv.h b/src/freedreno/drm/virtio/virtio_priv.h index d3773cef4b7..0effae6744c 100644 --- a/src/freedreno/drm/virtio/virtio_priv.h +++ b/src/freedreno/drm/virtio/virtio_priv.h @@ -173,6 +173,7 @@ struct fd_bo *virtio_bo_from_handle(struct fd_device *dev, uint32_t size, */ void *virtio_alloc_rsp(struct fd_device *dev, struct msm_ccmd_req *hdr, uint32_t sz); int virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req, + uint32_t *handles, uint32_t num_handles, int in_fence_fd, int *out_fence_fd, int ring_idx); int virtio_execbuf(struct fd_device *dev, struct msm_ccmd_req *req, bool sync); void virtio_host_sync(struct fd_device *dev, const struct msm_ccmd_req *req); diff --git a/src/freedreno/drm/virtio/virtio_ringbuffer.c b/src/freedreno/drm/virtio/virtio_ringbuffer.c index b104eb111f0..8744be3a49a 100644 --- a/src/freedreno/drm/virtio/virtio_ringbuffer.c +++ b/src/freedreno/drm/virtio/virtio_ringbuffer.c @@ -126,15 +126,21 @@ flush_submit_list(struct list_head *submit_list) struct drm_msm_gem_submit_bo _submit_bos[bos_on_stack ? fd_submit->nr_bos : 0]; struct drm_msm_gem_submit_bo *submit_bos; + uint32_t _guest_handles[bos_on_stack ? fd_submit->nr_bos : 0]; + uint32_t *guest_handles; if (bos_on_stack) { submit_bos = _submit_bos; + guest_handles = _guest_handles; } else { submit_bos = malloc(fd_submit->nr_bos * sizeof(submit_bos[0])); + guest_handles = malloc(fd_submit->nr_bos * sizeof(guest_handles[0])); } for (unsigned i = 0; i < fd_submit->nr_bos; i++) { struct virtio_bo *virtio_bo = to_virtio_bo(fd_submit->bos[i]); + guest_handles[i] = virtio_bo->base.handle; + submit_bos[i].flags = fd_submit->bos[i]->reloc_flags; submit_bos[i].handle = virtio_bo->res_id; submit_bos[i].presumed = 0; @@ -191,13 +197,16 @@ flush_submit_list(struct list_head *submit_list) req->flags |= MSM_SUBMIT_NO_IMPLICIT; } - virtio_execbuf_fenced(dev, &req->hdr, fd_submit->in_fence_fd, out_fence_fd, + virtio_execbuf_fenced(dev, &req->hdr, guest_handles, req->nr_bos, + fd_submit->in_fence_fd, out_fence_fd, virtio_pipe->ring_idx); free(req); - if (!bos_on_stack) + if (!bos_on_stack) { free(submit_bos); + free(guest_handles); + } if (fd_submit->in_fence_fd != -1) close(fd_submit->in_fence_fd);