This 3 patch series is the counterpart for this other series: https://lists.nongnu.org/archive/html/qemu-devel/2021-06/msg02906.html
It makes it possible for the Guest to wait until the Host has completely consumed its FB before reusing it again thereby ensuring that both the parties don't access it at the same time.
Cc: Gerd Hoffmann kraxel@redhat.com Cc: Dongwon Kim dongwon.kim@intel.com Cc: Tina Zhang tina.zhang@intel.com
Vivek Kasireddy (3): drm/virtio: Add fences for Guest blobs drm/virtio: Prepare resource_flush to accept a fence drm/virtio: Add the fence in resource_flush if present
drivers/gpu/drm/virtio/virtgpu_drv.h | 4 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 64 ++++++++++++++++++++------ drivers/gpu/drm/virtio/virtgpu_vq.c | 7 ++- 3 files changed, 59 insertions(+), 16 deletions(-)
Add prepare and cleanup routines for primary planes as well where a fence is added only if the BO/FB associated with the plane is a guest blob.
Cc: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Vivek Kasireddy vivek.kasireddy@intel.com --- drivers/gpu/drm/virtio/virtgpu_plane.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 4e1b17548007..dd7a1f2db9ad 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -206,8 +206,8 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, virtio_gpu_notify(vgdev); }
-static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state) +static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) { struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; @@ -219,7 +219,10 @@ static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
vgfb = to_virtio_gpu_framebuffer(new_state->fb); bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); - if (bo && bo->dumb && (plane->state->fb != new_state->fb)) { + if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) + return 0; + + if (bo->dumb && (plane->state->fb != new_state->fb)) { vgfb->fence = virtio_gpu_fence_alloc(vgdev); if (!vgfb->fence) return -ENOMEM; @@ -228,8 +231,8 @@ static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, return 0; }
-static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) +static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *old_state) { struct virtio_gpu_framebuffer *vgfb;
@@ -321,13 +324,15 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, }
static const struct drm_plane_helper_funcs virtio_gpu_primary_helper_funcs = { + .prepare_fb = virtio_gpu_plane_prepare_fb, + .cleanup_fb = virtio_gpu_plane_cleanup_fb, .atomic_check = virtio_gpu_plane_atomic_check, .atomic_update = virtio_gpu_primary_plane_update, };
static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = { - .prepare_fb = virtio_gpu_cursor_prepare_fb, - .cleanup_fb = virtio_gpu_cursor_cleanup_fb, + .prepare_fb = virtio_gpu_plane_prepare_fb, + .cleanup_fb = virtio_gpu_plane_cleanup_fb, .atomic_check = virtio_gpu_plane_atomic_check, .atomic_update = virtio_gpu_cursor_plane_update, };
A fence will be added to resource_flush for resources that are guest blobs.
Cc: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Vivek Kasireddy vivek.kasireddy@intel.com --- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 +++- drivers/gpu/drm/virtio/virtgpu_vq.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index d9dbc4f258f3..d4e610a44e12 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -315,7 +315,9 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, uint32_t resource_id, uint32_t x, uint32_t y, - uint32_t width, uint32_t height); + uint32_t width, uint32_t height, + struct virtio_gpu_object_array *objs, + struct virtio_gpu_fence *fence); void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, uint32_t scanout_id, uint32_t resource_id, uint32_t width, uint32_t height, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index cf84d382dd41..2e71e91278b4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -576,13 +576,16 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, uint32_t resource_id, uint32_t x, uint32_t y, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height, + struct virtio_gpu_object_array *objs, + struct virtio_gpu_fence *fence) { struct virtio_gpu_resource_flush *cmd_p; struct virtio_gpu_vbuffer *vbuf;
cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); + vbuf->objs = objs;
cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_FLUSH); cmd_p->resource_id = cpu_to_le32(resource_id); @@ -591,7 +594,7 @@ void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, cmd_p->r.x = cpu_to_le32(x); cmd_p->r.y = cpu_to_le32(y);
- virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); }
void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
If the framebuffer associated with the plane contains a fence, then it is added to resource_flush and will be waited upon for a max of 50 msecs or until it is signalled by the Host.
Cc: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Vivek Kasireddy vivek.kasireddy@intel.com --- drivers/gpu/drm/virtio/virtgpu_plane.c | 45 ++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index dd7a1f2db9ad..a49fd9480381 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -129,6 +129,40 @@ static void virtio_gpu_update_dumb_bo(struct virtio_gpu_device *vgdev, objs, NULL); }
+static void virtio_gpu_resource_flush(struct drm_plane *plane, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = plane->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_object *bo; + + vgfb = to_virtio_gpu_framebuffer(plane->state->fb); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); + if (vgfb->fence) { + struct virtio_gpu_object_array *objs; + + objs = virtio_gpu_array_alloc(1); + if (!objs) + return; + virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); + virtio_gpu_array_lock_resv(objs); + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, + width, height, objs, vgfb->fence); + virtio_gpu_notify(vgdev); + + dma_fence_wait_timeout(&vgfb->fence->f, true, + msecs_to_jiffies(50)); + dma_fence_put(&vgfb->fence->f); + vgfb->fence = NULL; + } else { + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, + width, height, NULL, NULL); + virtio_gpu_notify(vgdev); + } +} + static void virtio_gpu_primary_plane_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -198,12 +232,11 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, } }
- virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, - rect.x1, - rect.y1, - rect.x2 - rect.x1, - rect.y2 - rect.y1); - virtio_gpu_notify(vgdev); + virtio_gpu_resource_flush(plane, + rect.x1, + rect.y1, + rect.x2 - rect.x1, + rect.y2 - rect.y1); }
static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
On Thu, Jun 10, 2021 at 04:24:53PM -0700, Vivek Kasireddy wrote:
This 3 patch series is the counterpart for this other series: https://lists.nongnu.org/archive/html/qemu-devel/2021-06/msg02906.html
It makes it possible for the Guest to wait until the Host has completely consumed its FB before reusing it again thereby ensuring that both the parties don't access it at the same time.
Cc: Gerd Hoffmann kraxel@redhat.com Cc: Dongwon Kim dongwon.kim@intel.com Cc: Tina Zhang tina.zhang@intel.com
Vivek Kasireddy (3): drm/virtio: Add fences for Guest blobs drm/virtio: Prepare resource_flush to accept a fence drm/virtio: Add the fence in resource_flush if present
Pushed to drm-misc-next.
thanks, Gerd
dri-devel@lists.freedesktop.org