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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16086>
This commit is contained in:
Rob Clark 2022-04-12 14:09:03 -07:00 committed by Marge Bot
parent cb5f25ea71
commit 528fa581c1
3 changed files with 17 additions and 3 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);