diff mbox series

[v1,4/5] drm/virtio: Import prime buffers from other devices as guest blobs

Message ID 20240624064841.1572452-5-vivek.kasireddy@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/virtio: Import scanout buffers from other devices | expand

Commit Message

Kasireddy, Vivek June 24, 2024, 6:43 a.m. UTC
By importing scanout buffers from other devices, we should be able
to use the virtio-gpu driver in KMS only mode. Note that we attach
dynamically and register a move_notify() callback so that we can
let the VMM know of any location changes associated with the backing
store of the imported object by sending detach_backing cmd.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 drivers/gpu/drm/virtio/virtgpu_prime.c | 58 +++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

Comments

Dmitry Osipenko July 18, 2024, 7:33 p.m. UTC | #1
On 6/24/24 09:43, Vivek Kasireddy wrote:
> +static void virtgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
> +{
> +	struct drm_gem_object *obj = attach->importer_priv;
> +	struct virtio_gpu_device *vgdev = obj->dev->dev_private;
> +	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
> +
> +	if (bo->created) {
> +		virtio_gpu_cmd_resource_detach_backing(vgdev,
> +						       bo->hw_res_handle);
> +		if (bo->sgt)
> +			dma_buf_unmap_attachment(attach, bo->sgt,
> +						 DMA_BIDIRECTIONAL);
> +
> +		bo->sgt = NULL;
> +	}

BO detachment should be fenced, AFAICT. See
virtio_gpu_detach_object_fenced() in [1] for example.

[1]
https://lore.kernel.org/lkml/20240105184624.508603-1-dmitry.osipenko@collabora.com/T/#me62dca570fdae39c41bdf0867c9908ef62d5cc2e


BTW, for next version please correct the list of emails recipients. I
got only patch 0 in my inbox, for patches 1-5 only Gerd Hoffmann is CC'ed.
Kasireddy, Vivek July 20, 2024, 7:32 a.m. UTC | #2
Hi Dmitry,

> > +static void virtgpu_dma_buf_move_notify(struct dma_buf_attachment
> *attach)
> > +{
> > +	struct drm_gem_object *obj = attach->importer_priv;
> > +	struct virtio_gpu_device *vgdev = obj->dev->dev_private;
> > +	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
> > +
> > +	if (bo->created) {
> > +		virtio_gpu_cmd_resource_detach_backing(vgdev,
> > +						       bo->hw_res_handle);
> > +		if (bo->sgt)
> > +			dma_buf_unmap_attachment(attach, bo->sgt,
> > +						 DMA_BIDIRECTIONAL);
> > +
> > +		bo->sgt = NULL;
> > +	}
> 
> BO detachment should be fenced, AFAICT. See
> virtio_gpu_detach_object_fenced() in [1] for example.
> 
> [1]
> https://lore.kernel.org/lkml/20240105184624.508603-1-
> dmitry.osipenko@collabora.com/T/#me62dca570fdae39c41bdf0867c9908ef62
> d5cc2e
Ok, will test again on top of your changes.

> 
> 
> BTW, for next version please correct the list of emails recipients. I
> got only patch 0 in my inbox, for patches 1-5 only Gerd Hoffmann is CC'ed.
Sure, will include you and all virtio-gpu reviewers on all v2 patches.

Thanks,
Vivek

> 
> --
> Best regards,
> Dmitry
diff mbox series

Patch

diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index e9b5b5a7f8dc..12084b5b12eb 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -255,10 +255,40 @@  static int virtgpu_dma_buf_init_obj(struct drm_device *dev,
 	return ret;
 }
 
+static const struct drm_gem_object_funcs virtgpu_gem_dma_buf_funcs = {
+	.free = virtgpu_dma_buf_free_obj,
+};
+
+static void virtgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
+{
+	struct drm_gem_object *obj = attach->importer_priv;
+	struct virtio_gpu_device *vgdev = obj->dev->dev_private;
+	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
+
+	if (bo->created) {
+		virtio_gpu_cmd_resource_detach_backing(vgdev,
+						       bo->hw_res_handle);
+		if (bo->sgt)
+			dma_buf_unmap_attachment(attach, bo->sgt,
+						 DMA_BIDIRECTIONAL);
+
+		bo->sgt = NULL;
+	}
+}
+
+static const struct dma_buf_attach_ops virtgpu_dma_buf_attach_ops = {
+	.allow_peer2peer = true,
+	.move_notify = virtgpu_dma_buf_move_notify
+};
+
 struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 						struct dma_buf *buf)
 {
+	struct virtio_gpu_device *vgdev = dev->dev_private;
+	struct dma_buf_attachment *attach;
+	struct virtio_gpu_object *bo;
 	struct drm_gem_object *obj;
+	int ret;
 
 	if (buf->ops == &virtgpu_dmabuf_ops.ops) {
 		obj = buf->priv;
@@ -272,7 +302,32 @@  struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 		}
 	}
 
-	return drm_gem_prime_import(dev, buf);
+	if (!vgdev->has_resource_blob || vgdev->has_virgl_3d)
+		return drm_gem_prime_import(dev, buf);
+
+	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+	if (!bo)
+		return ERR_PTR(-ENOMEM);
+
+	obj = &bo->base.base;
+	obj->funcs = &virtgpu_gem_dma_buf_funcs;
+	drm_gem_private_object_init(dev, obj, buf->size);
+
+	attach = dma_buf_dynamic_attach(buf, dev->dev,
+					&virtgpu_dma_buf_attach_ops, obj);
+	if (IS_ERR(attach)) {
+		kfree(bo);
+		return ERR_CAST(attach);
+	}
+
+	obj->import_attach = attach;
+	get_dma_buf(buf);
+
+	ret = virtgpu_dma_buf_init_obj(dev, bo, attach);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	return obj;
 }
 
 struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
@@ -281,3 +336,4 @@  struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
 {
 	return ERR_PTR(-ENODEV);
 }
+