Hi Akihiko,

> Subject: Re: [RFC 3/6] virtio-gpu-udmabuf: Create dmabuf for blobs
> associated with VFIO devices
> 
> On 2025/09/03 7:42, Vivek Kasireddy wrote:
> > In addition to memfd, a blob resource can also have its backing
> > storage in a VFIO device region. Therefore, we first need to figure
> > out if the blob is backed by a VFIO device region or a memfd before
> > we can call the right API to get a dmabuf fd created.
> >
> > So, once we have the ramblock and the associated mr, we rely on
> > memory_region_is_ram_device() to tell us where the backing storage
> > is located. If the blob resource is VFIO backed, we try to find the
> > right VFIO device that contains the blob and then invoke the API
> > vfio_create_dmabuf().
> >
> > Note that we only call virtio_gpu_remap_udmabuf() if the blob is
> > backed by a memfd. This is because the VFIO dmabuf implementation
> > may not support mmap.
> >
> > Cc: Marc-André Lureau <marcandre.lur...@redhat.com>
> > Cc: Alex Bennée <alex.ben...@linaro.org>
> > Cc: Akihiko Odaki <od...@rsg.ci.i.u-tokyo.ac.jp>
> > Cc: Dmitry Osipenko <dmitry.osipe...@collabora.com>
> > Signed-off-by: Vivek Kasireddy <vivek.kasire...@intel.com>
> > ---
> >   hw/display/virtio-gpu-udmabuf.c | 60 ++++++++++++++++++++++++++++--
> ---
> >   1 file changed, 52 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-
> udmabuf.c
> > index d804f321aa..0390a8f488 100644
> > --- a/hw/display/virtio-gpu-udmabuf.c
> > +++ b/hw/display/virtio-gpu-udmabuf.c
> > @@ -18,6 +18,7 @@
> >   #include "ui/console.h"
> >   #include "hw/virtio/virtio-gpu.h"
> >   #include "hw/virtio/virtio-gpu-pixman.h"
> > +#include "hw/vfio/vfio-device.h"
> >   #include "trace.h"
> >   #include "system/ramblock.h"
> >   #include "system/hostmem.h"
> > @@ -27,6 +28,32 @@
> >   #include "standard-headers/linux/udmabuf.h"
> >   #include "standard-headers/drm/drm_fourcc.h"
> >
> > +static void vfio_create_dmabuf(VFIODevice *vdev,
> > +                               struct virtio_gpu_simple_resource *res)
> > +{
> > +    res->dmabuf_fd = vfio_device_create_dmabuf(vdev, res->iov, res-
> >iov_cnt);
> > +    if (res->dmabuf_fd < 0) {
> > +        warn_report("%s: VFIO_DEVICE_FEATURE_DMA_BUF: %s", __func__,
> > +                    strerror(errno));
> > +    }
> > +}
> > +
> > +static VFIODevice *vfio_device_lookup(MemoryRegion *mr)
> > +{
> > +    VFIODevice *vdev;
> > +
> > +    if (QLIST_EMPTY(&vfio_device_list)) {
> > +        return NULL;
> > +    }
> 
> I think this QLIST_EMPTY() check can be removed.
Yeah, agreed. I'll remove it.

> 
> > +
> > +    QLIST_FOREACH(vdev, &vfio_device_list, next) {
> > +        if (vdev->dev == mr->dev) {
> > +            return vdev;
> > +        }
> > +    }
> > +    return NULL;
> > +}
> > +
> >   static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource
> *res)
> >   {
> >       struct udmabuf_create_list *list;
> > @@ -130,6 +157,9 @@ bool virtio_gpu_have_udmabuf(void)
> >
> >   void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> >   {
> > +    bool memfd_blob = false;
> > +    ram_addr_t offset;
> > +    RAMBlock *rb;
> >       void *pdata = NULL;
> >
> >       res->dmabuf_fd = -1;
> > @@ -137,15 +167,31 @@ void virtio_gpu_init_udmabuf(struct
> virtio_gpu_simple_resource *res)
> >           res->iov[0].iov_len < 4096) {
> >           pdata = res->iov[0].iov_base;
> >       } else {
> > -        virtio_gpu_create_udmabuf(res);
> > +        rb = qemu_ram_block_from_host(res->iov[0].iov_base, false,
> &offset);
> > +        if (rb && memory_region_is_ram_device(rb->mr)) {
> > +            VFIODevice *vdev = vfio_device_lookup(rb->mr);
> > +
> > +            if (!vdev) {
> > +                warn_report("Could not find device to create dmabuf");
> 
> It is odd to print a warning only when the memory region is a RAM device
> not backed by VFIO while it prints no warning for the other incompatible
> memory regions. It is better to keep the behavior for the incompatible
> memory regions consistent.
Ok, I'll have the warning printed in other incompatible cases as well.

Thanks,
Vivek

> 
> > +                return;
> > +            }
> > +            vfio_create_dmabuf(vdev, res);
> > +        } else {
> > +            virtio_gpu_create_udmabuf(res);
> > +            memfd_blob = true;
> > +        }
> > +
> >           if (res->dmabuf_fd < 0) {
> >               return;
> >           }
> > -        virtio_gpu_remap_udmabuf(res);
> > -        if (!res->remapped) {
> > -            return;
> > +
> > +        if (memfd_blob) {
> > +            virtio_gpu_remap_udmabuf(res);
> > +            if (!res->remapped) {
> > +                return;
> > +            }
> > +            pdata = res->remapped;
> >           }
> > -        pdata = res->remapped;
> >       }
> >
> >       res->blob = pdata;
> > @@ -153,9 +199,7 @@ void virtio_gpu_init_udmabuf(struct
> virtio_gpu_simple_resource *res)
> >
> >   void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
> >   {
> > -    if (res->remapped) {
> > -        virtio_gpu_destroy_udmabuf(res);
> > -    }
> > +    virtio_gpu_destroy_udmabuf(res);
> >   }
> >
> >   static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf
> *dmabuf)


Reply via email to