Module: Mesa
Branch: main
Commit: 76fbc8be6d484e35995121eeb90b01daa89b4343
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=76fbc8be6d484e35995121eeb90b01daa89b4343

Author: Rob Clark <[email protected]>
Date:   Wed Sep 14 14:06:15 2022 -0700

freedreno/drm/virtio: Handle read after upload

If we get CPU access (such as a read) after an upload transfer, we need
to ensure that the host has handled the upload.  Do this by stalling
when the buffer is mapped.  (The previous commit ensures we don't try to
do a pointless upload for an already mapped buffer.)

Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18604>

---

 src/freedreno/drm/virtio/virtio_bo.c   | 20 +++++++++++++++++++-
 src/freedreno/drm/virtio/virtio_priv.h |  2 ++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/freedreno/drm/virtio/virtio_bo.c 
b/src/freedreno/drm/virtio/virtio_bo.c
index 85ab2504c6e..7636f3948d1 100644
--- a/src/freedreno/drm/virtio/virtio_bo.c
+++ b/src/freedreno/drm/virtio/virtio_bo.c
@@ -52,9 +52,23 @@ virtio_bo_offset(struct fd_bo *bo, uint64_t *offset)
 {
    struct virtio_bo *virtio_bo = to_virtio_bo(bo);
    int ret = bo_allocate(virtio_bo);
+
    if (ret)
       return ret;
+
+   /* If we have uploaded, we need to wait for host to handle that
+    * before we can allow guest-side CPU access:
+    */
+   if (virtio_bo->has_upload_seqno) {
+      virtio_bo->has_upload_seqno = false;
+      virtio_execbuf_flush(bo->dev);
+      virtio_host_sync(bo->dev, &(struct msm_ccmd_req) {
+         .seqno = virtio_bo->upload_seqno,
+      });
+   }
+
    *offset = virtio_bo->offset;
+
    return 0;
 }
 
@@ -186,12 +200,13 @@ static void
 bo_upload(struct fd_bo *bo, unsigned off, void *src, unsigned len)
 {
    unsigned req_len = sizeof(struct msm_ccmd_gem_upload_req) + align(len, 4);
+   struct virtio_bo *virtio_bo = to_virtio_bo(bo);
 
    uint8_t buf[req_len];
    struct msm_ccmd_gem_upload_req *req = (void *)buf;
 
    req->hdr = MSM_CCMD(GEM_UPLOAD, req_len);
-   req->res_id = to_virtio_bo(bo)->res_id;
+   req->res_id = virtio_bo->res_id;
    req->pad = 0;
    req->off = off;
    req->len = len;
@@ -199,6 +214,9 @@ bo_upload(struct fd_bo *bo, unsigned off, void *src, 
unsigned len)
    memcpy(req->payload, src, len);
 
    virtio_execbuf(bo->dev, &req->hdr, false);
+
+   virtio_bo->upload_seqno = req->hdr.seqno;
+   virtio_bo->has_upload_seqno = true;
 }
 
 static void
diff --git a/src/freedreno/drm/virtio/virtio_priv.h 
b/src/freedreno/drm/virtio/virtio_priv.h
index 32ff89acdfb..c210a2b05b7 100644
--- a/src/freedreno/drm/virtio/virtio_priv.h
+++ b/src/freedreno/drm/virtio/virtio_priv.h
@@ -174,6 +174,8 @@ struct virtio_bo {
    uint64_t offset;
    uint32_t res_id;
    uint32_t blob_id;
+   uint32_t upload_seqno;
+   bool has_upload_seqno;
 };
 FD_DEFINE_CAST(fd_bo, virtio_bo);
 

Reply via email to