diff options
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/Kconfig | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_debugfs.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fence.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_gem.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_kms.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_vram.c | 3 |
8 files changed, 75 insertions, 47 deletions
diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig index b925b8b1da16..51ec7c3240c9 100644 --- a/drivers/gpu/drm/virtio/Kconfig +++ b/drivers/gpu/drm/virtio/Kconfig @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only config DRM_VIRTIO_GPU tristate "Virtio GPU driver" - depends on DRM && VIRTIO && VIRTIO_MENU && MMU + depends on DRM && VIRTIO_MENU && MMU + select VIRTIO select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select VIRTIO_DMA_SHARED_BUFFER diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 5fefc88d47e4..c2b20e0ee030 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -28,14 +28,13 @@ #include "virtgpu_drv.h" -static void virtio_add_bool(struct seq_file *m, const char *name, - bool value) +static void virtio_gpu_add_bool(struct seq_file *m, const char *name, + bool value) { seq_printf(m, "%-16s : %s\n", name, value ? "yes" : "no"); } -static void virtio_add_int(struct seq_file *m, const char *name, - int value) +static void virtio_gpu_add_int(struct seq_file *m, const char *name, int value) { seq_printf(m, "%-16s : %d\n", name, value); } @@ -45,13 +44,16 @@ static int virtio_gpu_features(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; - virtio_add_bool(m, "virgl", vgdev->has_virgl_3d); - virtio_add_bool(m, "edid", vgdev->has_edid); - virtio_add_bool(m, "indirect", vgdev->has_indirect); - virtio_add_bool(m, "resource uuid", vgdev->has_resource_assign_uuid); - virtio_add_bool(m, "blob resources", vgdev->has_resource_blob); - virtio_add_int(m, "cap sets", vgdev->num_capsets); - virtio_add_int(m, "scanouts", vgdev->num_scanouts); + virtio_gpu_add_bool(m, "virgl", vgdev->has_virgl_3d); + virtio_gpu_add_bool(m, "edid", vgdev->has_edid); + virtio_gpu_add_bool(m, "indirect", vgdev->has_indirect); + + virtio_gpu_add_bool(m, "resource uuid", + vgdev->has_resource_assign_uuid); + + virtio_gpu_add_bool(m, "blob resources", vgdev->has_resource_blob); + virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets); + virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts); if (vgdev->host_visible_region.len) { seq_printf(m, "%-16s : 0x%lx +0x%lx\n", "host visible region", (unsigned long)vgdev->host_visible_region.addr, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 27f13bd29c13..a21dc3ad6f88 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -54,7 +54,6 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vd DRM_INFO("pci: %s detected at %s\n", vga ? "virtio-vga" : "virtio-gpu-pci", pname); - dev->pdev = pdev; if (vga) drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "virtiodrmfb"); diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 6a232553c99b..d9dbc4f258f3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -136,6 +136,7 @@ struct virtio_gpu_fence_driver { struct virtio_gpu_fence { struct dma_fence f; + uint64_t fence_id; struct virtio_gpu_fence_driver *drv; struct list_head node; }; diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 728ca36f6327..d28e25e8409b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -27,51 +27,48 @@ #include "virtgpu_drv.h" -#define to_virtio_fence(x) \ +#define to_virtio_gpu_fence(x) \ container_of(x, struct virtio_gpu_fence, f) -static const char *virtio_get_driver_name(struct dma_fence *f) +static const char *virtio_gpu_get_driver_name(struct dma_fence *f) { return "virtio_gpu"; } -static const char *virtio_get_timeline_name(struct dma_fence *f) +static const char *virtio_gpu_get_timeline_name(struct dma_fence *f) { return "controlq"; } -static bool virtio_fence_signaled(struct dma_fence *f) +static bool virtio_gpu_fence_signaled(struct dma_fence *f) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); - - if (WARN_ON_ONCE(fence->f.seqno == 0)) - /* leaked fence outside driver before completing - * initialization with virtio_gpu_fence_emit */ - return false; - if (atomic64_read(&fence->drv->last_fence_id) >= fence->f.seqno) - return true; + /* leaked fence outside driver before completing + * initialization with virtio_gpu_fence_emit. + */ + WARN_ON_ONCE(f->seqno == 0); return false; } -static void virtio_fence_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_fence_value_str(struct dma_fence *f, char *str, int size) { - snprintf(str, size, "%llu", f->seqno); + snprintf(str, size, "[%llu, %llu]", f->context, f->seqno); } -static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_timeline_value_str(struct dma_fence *f, char *str, + int size) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); + struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_fence_id)); } -static const struct dma_fence_ops virtio_fence_ops = { - .get_driver_name = virtio_get_driver_name, - .get_timeline_name = virtio_get_timeline_name, - .signaled = virtio_fence_signaled, - .fence_value_str = virtio_fence_value_str, - .timeline_value_str = virtio_timeline_value_str, +static const struct dma_fence_ops virtio_gpu_fence_ops = { + .get_driver_name = virtio_gpu_get_driver_name, + .get_timeline_name = virtio_gpu_get_timeline_name, + .signaled = virtio_gpu_fence_signaled, + .fence_value_str = virtio_gpu_fence_value_str, + .timeline_value_str = virtio_gpu_timeline_value_str, }; struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) @@ -88,7 +85,8 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) * unknown yet. The fence must not be used outside of the driver * until virtio_gpu_fence_emit is called. */ - dma_fence_init(&fence->f, &virtio_fence_ops, &drv->lock, drv->context, 0); + dma_fence_init(&fence->f, &virtio_gpu_fence_ops, &drv->lock, drv->context, + 0); return fence; } @@ -101,7 +99,7 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); - fence->f.seqno = ++drv->current_fence_id; + fence->fence_id = fence->f.seqno = ++drv->current_fence_id; dma_fence_get(&fence->f); list_add_tail(&fence->node, &drv->fences); spin_unlock_irqrestore(&drv->lock, irq_flags); @@ -109,24 +107,45 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, trace_dma_fence_emit(&fence->f); cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); - cmd_hdr->fence_id = cpu_to_le64(fence->f.seqno); + cmd_hdr->fence_id = cpu_to_le64(fence->fence_id); } void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, u64 fence_id) { struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; - struct virtio_gpu_fence *fence, *tmp; + struct virtio_gpu_fence *signaled, *curr, *tmp; unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); atomic64_set(&vgdev->fence_drv.last_fence_id, fence_id); - list_for_each_entry_safe(fence, tmp, &drv->fences, node) { - if (fence_id < fence->f.seqno) + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + if (fence_id != curr->fence_id) continue; - dma_fence_signal_locked(&fence->f); - list_del(&fence->node); - dma_fence_put(&fence->f); + + signaled = curr; + + /* + * Signal any fences with a strictly smaller sequence number + * than the current signaled fence. + */ + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + /* dma-fence contexts must match */ + if (signaled->f.context != curr->f.context) + continue; + + if (!dma_fence_is_later(&signaled->f, &curr->f)) + continue; + + dma_fence_signal_locked(&curr->f); + list_del(&curr->node); + dma_fence_put(&curr->f); + } + + dma_fence_signal_locked(&signaled->f); + list_del(&signaled->node); + dma_fence_put(&signaled->f); + break; } spin_unlock_irqrestore(&drv->lock, irq_flags); } diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index c30c75ee83fc..8502400b2f9c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -39,9 +39,6 @@ static int virtio_gpu_gem_create(struct drm_file *file, int ret; u32 handle; - if (vgdev->has_virgl_3d) - virtio_gpu_create_context(dev, file); - ret = virtio_gpu_object_create(vgdev, params, &obj, NULL); if (ret < 0) return ret; @@ -119,6 +116,11 @@ int virtio_gpu_gem_object_open(struct drm_gem_object *obj, if (!vgdev->has_virgl_3d) goto out_notify; + /* the context might still be missing when the first ioctl is + * DRM_IOCTL_MODE_CREATE_DUMB or DRM_IOCTL_PRIME_FD_TO_HANDLE + */ + virtio_gpu_create_context(obj->dev, file); + objs = virtio_gpu_array_alloc(1); if (!objs) return -ENOMEM; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index b4ec479c32cd..b375394193be 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -163,6 +163,7 @@ int virtio_gpu_init(struct drm_device *dev) vgdev->host_visible_region.len, dev_name(&vgdev->vdev->dev))) { DRM_ERROR("Could not reserve host visible region\n"); + ret = -EBUSY; goto err_vqs; } diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c index 23c21bc4d01e..5cc34e7330fa 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vram.c +++ b/drivers/gpu/drm/virtio/virtgpu_vram.c @@ -69,6 +69,7 @@ static const struct drm_gem_object_funcs virtio_gpu_vram_funcs = { .close = virtio_gpu_gem_object_close, .free = virtio_gpu_vram_free, .mmap = virtio_gpu_vram_mmap, + .export = virtgpu_gem_prime_export, }; bool virtio_gpu_is_vram(struct virtio_gpu_object *bo) @@ -134,6 +135,8 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, obj = &vram->base.base.base; obj->funcs = &virtio_gpu_vram_funcs; + + params->size = PAGE_ALIGN(params->size); drm_gem_private_object_init(vgdev->ddev, obj, params->size); /* Create fake offset */ |