vhost-user-gpu: fix vugbm_device_init fallback

vugbm implements GBM device wrapping, udmabuf and memory fallback.
However, the fallback/detection logic is flawed, as if "/dev/udmabuf"
failed to be opened, it will not initialize vugbm and crash later.

Rework the vugbm_device_init() logic to initialize correctly in all
cases.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210312100108.2706195-4-marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Marc-André Lureau 2021-03-12 14:00:44 +04:00 committed by Gerd Hoffmann
parent 0c27b9c568
commit 96ee096a13
3 changed files with 22 additions and 30 deletions

View File

@ -1186,11 +1186,7 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (g.drm_rnode_fd >= 0) { vugbm_device_init(&g.gdev, g.drm_rnode_fd);
if (!vugbm_device_init(&g.gdev, g.drm_rnode_fd)) {
g_warning("Failed to init DRM device, using fallback path");
}
}
if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) { if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) {
g_printerr("Please specify either --fd or --socket-path\n"); g_printerr("Please specify either --fd or --socket-path\n");

View File

@ -199,55 +199,51 @@ vugbm_device_destroy(struct vugbm_device *dev)
dev->device_destroy(dev); dev->device_destroy(dev);
} }
bool void
vugbm_device_init(struct vugbm_device *dev, int fd) vugbm_device_init(struct vugbm_device *dev, int fd)
{ {
dev->fd = fd; assert(!dev->inited);
#ifdef CONFIG_GBM #ifdef CONFIG_GBM
dev->dev = gbm_create_device(fd); if (fd >= 0) {
#endif dev->dev = gbm_create_device(fd);
if (0) {
/* nothing */
} }
#ifdef CONFIG_GBM if (dev->dev != NULL) {
else if (dev->dev != NULL) { dev->fd = fd;
dev->alloc_bo = alloc_bo; dev->alloc_bo = alloc_bo;
dev->free_bo = free_bo; dev->free_bo = free_bo;
dev->get_fd = get_fd; dev->get_fd = get_fd;
dev->map_bo = map_bo; dev->map_bo = map_bo;
dev->unmap_bo = unmap_bo; dev->unmap_bo = unmap_bo;
dev->device_destroy = device_destroy; dev->device_destroy = device_destroy;
dev->inited = true;
} }
#endif #endif
#ifdef CONFIG_MEMFD #ifdef CONFIG_MEMFD
else if (g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) { if (!dev->inited && g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) {
dev->fd = open("/dev/udmabuf", O_RDWR); dev->fd = open("/dev/udmabuf", O_RDWR);
if (dev->fd < 0) { if (dev->fd >= 0) {
return false; g_debug("Using experimental udmabuf backend");
dev->alloc_bo = udmabuf_alloc_bo;
dev->free_bo = udmabuf_free_bo;
dev->get_fd = udmabuf_get_fd;
dev->map_bo = udmabuf_map_bo;
dev->unmap_bo = udmabuf_unmap_bo;
dev->device_destroy = udmabuf_device_destroy;
dev->inited = true;
} }
g_debug("Using experimental udmabuf backend");
dev->alloc_bo = udmabuf_alloc_bo;
dev->free_bo = udmabuf_free_bo;
dev->get_fd = udmabuf_get_fd;
dev->map_bo = udmabuf_map_bo;
dev->unmap_bo = udmabuf_unmap_bo;
dev->device_destroy = udmabuf_device_destroy;
} }
#endif #endif
else { if (!dev->inited) {
g_debug("Using mem fallback"); g_debug("Using mem fallback");
dev->alloc_bo = mem_alloc_bo; dev->alloc_bo = mem_alloc_bo;
dev->free_bo = mem_free_bo; dev->free_bo = mem_free_bo;
dev->map_bo = mem_map_bo; dev->map_bo = mem_map_bo;
dev->unmap_bo = mem_unmap_bo; dev->unmap_bo = mem_unmap_bo;
dev->device_destroy = mem_device_destroy; dev->device_destroy = mem_device_destroy;
return false; dev->inited = true;
} }
assert(dev->inited);
dev->inited = true;
return true;
} }
static bool static bool

View File

@ -54,7 +54,7 @@ struct vugbm_buffer {
uint32_t format; uint32_t format;
}; };
bool vugbm_device_init(struct vugbm_device *dev, int fd); void vugbm_device_init(struct vugbm_device *dev, int fd);
void vugbm_device_destroy(struct vugbm_device *dev); void vugbm_device_destroy(struct vugbm_device *dev);
bool vugbm_buffer_create(struct vugbm_buffer *buffer, struct vugbm_device *dev, bool vugbm_buffer_create(struct vugbm_buffer *buffer, struct vugbm_device *dev,