OSDN Git Service

minigbm: virtio-gpu: bo_invalidate fixes
authorDavid Stevens <stevensd@chromium.org>
Thu, 24 Oct 2019 05:59:31 +0000 (14:59 +0900)
committerchrome-bot <chrome-bot@chromium.org>
Sat, 26 Oct 2019 12:05:14 +0000 (05:05 -0700)
When invalidating a buffer, minigbm needs to ensure that the
host-to-guest transfer completes before returning from invalidate, to
prevent the host from overwriting subsequent guest changes.

However, invalidate is only necessary when the host can modify the
buffer. For now, just check for buffers the virtio gpu device can write
to (BO_USE_RENDERING). More flags can be added later for other virtio
devices.

BUG=b:142687692
TEST=manual - Launch play store and verify there is no black app window.
Change-Id: Id9475e6037ff667324f4fd95a94b1723c18ea2d2
Reviewed-on: https://chromium-review.googlesource.com/1875897
Tested-by: David Stevens <stevensd@chromium.org>
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Reviewed-by: Lepton Wu <lepton@chromium.org>
virtio_gpu.c

index 9e5b0ba..daeafde 100644 (file)
@@ -263,10 +263,15 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping)
        int ret;
        struct drm_virtgpu_3d_transfer_from_host xfer;
        struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv;
+       struct drm_virtgpu_3d_wait waitcmd;
 
        if (!priv->has_3d)
                return 0;
 
+       // Invalidate is only necessary if the host writes to the buffer.
+       if ((bo->meta.use_flags & BO_USE_RENDERING) == 0)
+               return 0;
+
        memset(&xfer, 0, sizeof(xfer));
        xfer.bo_handle = mapping->vma->handle;
        xfer.box.x = mapping->rect.x;
@@ -286,6 +291,17 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping)
                return -errno;
        }
 
+       // The transfer needs to complete before invalidate returns so that any host changes
+       // are visible and to ensure the host doesn't overwrite subsequent guest changes.
+       // TODO(b/136733358): Support returning fences from transfers
+       memset(&waitcmd, 0, sizeof(waitcmd));
+       waitcmd.handle = mapping->vma->handle;
+       ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd);
+       if (ret) {
+               drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
+               return -errno;
+       }
+
        return 0;
 }