Make qemu_dmabuf_free() call qemu_dmabuf_close(), so the dmabuf always owns and closes its fds. This removes the need for callers to explicitly close fds before freeing and simplify the code.
To support this, virtio_gpu_create_dmabuf() now dup()s the resource fd so each QemuDmaBuf has an independent copy. The scanout-matching loop in virtio_gpu_fini_udmabuf() is no longer needed and is removed. Signed-off-by: Marc-André Lureau <[email protected]> --- hw/display/vhost-user-gpu.c | 1 - hw/display/virtio-gpu-udmabuf-stubs.c | 2 +- hw/display/virtio-gpu-udmabuf.c | 32 +++++++++----------------------- hw/display/virtio-gpu.c | 2 +- hw/vfio/display.c | 1 - include/hw/virtio/virtio-gpu.h | 3 +-- include/ui/dmabuf.h | 1 - ui/dbus-listener.c | 1 - ui/dmabuf.c | 22 ++++++++-------------- 9 files changed, 20 insertions(+), 45 deletions(-) diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index cd684d63639e..c09aca041135 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -293,7 +293,6 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) dmabuf = g->dmabuf[m->scanout_id]; if (dmabuf) { - qemu_dmabuf_close(dmabuf); qemu_console_gl_release_dmabuf(con, dmabuf); g_clear_pointer(&dmabuf, qemu_dmabuf_free); } diff --git a/hw/display/virtio-gpu-udmabuf-stubs.c b/hw/display/virtio-gpu-udmabuf-stubs.c index 85d03935a332..f692e1351034 100644 --- a/hw/display/virtio-gpu-udmabuf-stubs.c +++ b/hw/display/virtio-gpu-udmabuf-stubs.c @@ -12,7 +12,7 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) /* nothing (stub) */ } -void virtio_gpu_fini_udmabuf(VirtIOGPU *g, struct virtio_gpu_simple_resource *res) +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res) { /* nothing (stub) */ } diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index fd47028a1189..094646af8636 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -79,7 +79,7 @@ static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res) } } -static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *res) +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res) { if (res->remapped) { munmap(res->remapped, res->blob_size); @@ -143,7 +143,7 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) } virtio_gpu_remap_udmabuf(res); if (!res->remapped) { - virtio_gpu_destroy_udmabuf(res); + virtio_gpu_fini_udmabuf(res); return; } pdata = res->remapped; @@ -152,42 +152,28 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) res->blob = pdata; } -void virtio_gpu_fini_udmabuf(VirtIOGPU *g, struct virtio_gpu_simple_resource *res) -{ - int max_outputs = g->parent_obj.conf.max_outputs; - int i; - - for (i = 0; i < max_outputs; i++) { - struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[i]; - - if (scanout->dmabuf && - qemu_dmabuf_get_num_planes(scanout->dmabuf) > 0 && - qemu_dmabuf_get_fds(scanout->dmabuf, NULL)[0] == res->dmabuf_fd && - res->dmabuf_fd != -1) { - qemu_dmabuf_close(scanout->dmabuf); - res->dmabuf_fd = -1; - } - } - - virtio_gpu_destroy_udmabuf(res); -} - static QemuDmaBuf * virtio_gpu_create_dmabuf(struct virtio_gpu_simple_resource *res, struct virtio_gpu_framebuffer *fb, struct virtio_gpu_rect *r) { uint32_t offset = 0; + int fd; if (res->dmabuf_fd < 0) { return NULL; } + fd = qemu_dup(res->dmabuf_fd); + if (fd < 0) { + return NULL; + } + return qemu_dmabuf_new(r->width, r->height, &offset, &fb->stride, r->x, r->y, fb->width, fb->height, qemu_pixman_to_drm_format(fb->format), - DRM_FORMAT_MOD_INVALID, &res->dmabuf_fd, + DRM_FORMAT_MOD_INVALID, &fd, 1, true, false); } diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index fbb6fec7a0ad..0335b636068d 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -978,7 +978,7 @@ void virtio_gpu_cleanup_mapping(VirtIOGPU *g, res->addrs = NULL; if (res->blob) { - virtio_gpu_fini_udmabuf(g, res); + virtio_gpu_fini_udmabuf(res); } } diff --git a/hw/vfio/display.c b/hw/vfio/display.c index cb83d98e9af6..89854eceb43c 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -263,7 +263,6 @@ static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf) { QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next); - qemu_dmabuf_close(dmabuf->buf); qemu_console_gl_release_dmabuf(dpy->con, dmabuf->buf); g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); g_free(dmabuf); diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 79eb4b1b8cec..d3ca8d82586b 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -379,8 +379,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb, /* virtio-gpu-udmabuf.c */ bool virtio_gpu_have_udmabuf(void); void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); -void virtio_gpu_fini_udmabuf(VirtIOGPU *g, - struct virtio_gpu_simple_resource *res); +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res); int virtio_gpu_update_dmabuf(VirtIOGPU *g, uint32_t scanout_id, struct virtio_gpu_simple_resource *res, diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h index 381583bd536c..e47b96b454dd 100644 --- a/include/ui/dmabuf.h +++ b/include/ui/dmabuf.h @@ -27,7 +27,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free); const int *qemu_dmabuf_get_fds(QemuDmaBuf *dmabuf, int *nfds); void qemu_dmabuf_dup_fds(QemuDmaBuf *dmabuf, int *fds, int nfds); -void qemu_dmabuf_close(QemuDmaBuf *dmabuf); uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf); uint32_t qemu_dmabuf_get_height(QemuDmaBuf *dmabuf); const uint32_t *qemu_dmabuf_get_offsets(QemuDmaBuf *dmabuf, int *noffsets); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 5a72c7eeae59..c1e86648384c 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -631,7 +631,6 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl, if (dbus_call_scanout_dmabuf(ddl, dmabuf)) { ddl->scanout_dmabuf = NULL; } - qemu_dmabuf_close(dmabuf); #endif #ifdef WIN32 diff --git a/ui/dmabuf.c b/ui/dmabuf.c index b61dc7ad2783..3651f784bd14 100644 --- a/ui/dmabuf.c +++ b/ui/dmabuf.c @@ -62,10 +62,18 @@ QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, void qemu_dmabuf_free(QemuDmaBuf *dmabuf) { + int i; + if (dmabuf == NULL) { return; } + for (i = 0; i < dmabuf->num_planes; i++) { + if (dmabuf->fd[i] >= 0) { + close(dmabuf->fd[i]); + dmabuf->fd[i] = -1; + } + } g_free(dmabuf); } @@ -92,20 +100,6 @@ void qemu_dmabuf_dup_fds(QemuDmaBuf *dmabuf, int *fds, int nfds) } } -void qemu_dmabuf_close(QemuDmaBuf *dmabuf) -{ - int i; - - assert(dmabuf != NULL); - - for (i = 0; i < dmabuf->num_planes; i++) { - if (dmabuf->fd[i] >= 0) { - close(dmabuf->fd[i]); - dmabuf->fd[i] = -1; - } - } -} - uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf) { assert(dmabuf != NULL); -- 2.55.0.543.g5ebe2ebe4ea8
