diff options
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_debugfs.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fence.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_gem.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_ioctl.c | 107 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_object.c | 74 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_prime.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_ttm.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_vq.c | 36 |
10 files changed, 219 insertions, 234 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 73dc99046c43..ed0fcda713c3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -28,6 +28,30 @@ #include "virtgpu_drv.h" +static void virtio_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) +{ + seq_printf(m, "%-16s : %d\n", name, value); +} + +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_int(m, "cap sets", vgdev->num_capsets); + virtio_add_int(m, "scanouts", vgdev->num_scanouts); + return 0; +} + static int virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data) { @@ -41,7 +65,8 @@ virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data) } static struct drm_info_list virtio_gpu_debugfs_list[] = { - { "irq_fence", virtio_gpu_debugfs_irq_info, 0, NULL }, + { "virtio-gpu-features", virtio_gpu_features }, + { "virtio-gpu-irq-fence", virtio_gpu_debugfs_irq_info, 0, NULL }, }; #define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index b996ac1d4fcc..7c2893181ba4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -205,10 +205,10 @@ static struct drm_driver driver = { #if defined(CONFIG_DEBUG_FS) .debugfs_init = virtio_gpu_debugfs_init, #endif + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .gem_prime_export = drm_gem_prime_export, .gem_prime_import = drm_gem_prime_import, - .gem_prime_pin = virtgpu_gem_prime_pin, - .gem_prime_unpin = virtgpu_gem_prime_unpin, + .gem_prime_get_sg_table = virtgpu_gem_prime_get_sg_table, .gem_prime_vmap = virtgpu_gem_prime_vmap, .gem_prime_vunmap = virtgpu_gem_prime_vunmap, .gem_prime_mmap = virtgpu_gem_prime_mmap, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 3238fdf58eb4..491dec0712b3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -50,6 +50,23 @@ #define DRIVER_MINOR 1 #define DRIVER_PATCHLEVEL 0 +struct virtio_gpu_object_params { + uint32_t format; + uint32_t width; + uint32_t height; + unsigned long size; + bool dumb; + /* 3d */ + bool virgl; + uint32_t target; + uint32_t bind; + uint32_t depth; + uint32_t array_size; + uint32_t last_level; + uint32_t nr_samples; + uint32_t flags; +}; + struct virtio_gpu_object { struct drm_gem_object gem_base; uint32_t hw_res_handle; @@ -204,6 +221,9 @@ struct virtio_gpu_fpriv { /* virtio_ioctl.c */ #define DRM_VIRTIO_NUM_IOCTLS 10 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; +int virtio_gpu_object_list_validate(struct ww_acquire_ctx *ticket, + struct list_head *head); +void virtio_gpu_unref_list(struct list_head *head); /* virtio_kms.c */ int virtio_gpu_init(struct drm_device *dev); @@ -217,16 +237,17 @@ int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev); void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev); int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev, - uint64_t size, + struct virtio_gpu_object_params *params, struct drm_gem_object **obj_p, uint32_t *handle_p); int virtio_gpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file); void virtio_gpu_gem_object_close(struct drm_gem_object *obj, struct drm_file *file); -struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, - size_t size, bool kernel, - bool pinned); +struct virtio_gpu_object* +virtio_gpu_alloc_object(struct drm_device *dev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence); int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); @@ -243,9 +264,8 @@ int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - uint32_t format, - uint32_t width, - uint32_t height); + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence); void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, uint32_t resource_id); void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, @@ -304,7 +324,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - struct virtio_gpu_resource_create_3d *rc_3d); + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence); void virtio_gpu_ctrl_ack(struct virtqueue *vq); void virtio_gpu_cursor_ack(struct virtqueue *vq); void virtio_gpu_fence_ack(struct virtqueue *vq); @@ -332,6 +353,7 @@ void virtio_gpu_ttm_fini(struct virtio_gpu_device *vgdev); int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma); /* virtio_gpu_fence.c */ +bool virtio_fence_signaled(struct dma_fence *f); struct virtio_gpu_fence *virtio_gpu_fence_alloc( struct virtio_gpu_device *vgdev); int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, @@ -342,8 +364,9 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, /* virtio_gpu_object */ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, - unsigned long size, bool kernel, bool pinned, - struct virtio_gpu_object **bo_ptr); + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr, + struct virtio_gpu_fence *fence); void virtio_gpu_object_kunmap(struct virtio_gpu_object *bo); int virtio_gpu_object_kmap(struct virtio_gpu_object *bo); int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev, @@ -352,8 +375,7 @@ void virtio_gpu_object_free_sg_table(struct virtio_gpu_object *bo); int virtio_gpu_object_wait(struct virtio_gpu_object *bo, bool no_wait); /* virtgpu_prime.c */ -int virtgpu_gem_prime_pin(struct drm_gem_object *obj); -void virtgpu_gem_prime_unpin(struct drm_gem_object *obj); +struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj); void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj); void virtgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); int virtgpu_gem_prime_mmap(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 21bd4c4a32d1..87d1966192f4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -36,7 +36,7 @@ static const char *virtio_get_timeline_name(struct dma_fence *f) return "controlq"; } -static bool virtio_signaled(struct dma_fence *f) +bool virtio_fence_signaled(struct dma_fence *f) { struct virtio_gpu_fence *fence = to_virtio_fence(f); @@ -62,7 +62,7 @@ static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size) 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_signaled, + .signaled = virtio_fence_signaled, .fence_value_str = virtio_fence_value_str, .timeline_value_str = virtio_timeline_value_str, }; diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index f06586393974..1e49e08dd545 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -34,15 +34,16 @@ void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj) virtio_gpu_object_unref(&obj); } -struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, - size_t size, bool kernel, - bool pinned) +struct virtio_gpu_object* +virtio_gpu_alloc_object(struct drm_device *dev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence) { struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_object *obj; int ret; - ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj); + ret = virtio_gpu_object_create(vgdev, params, &obj, fence); if (ret) return ERR_PTR(ret); @@ -51,7 +52,7 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev, - uint64_t size, + struct virtio_gpu_object_params *params, struct drm_gem_object **obj_p, uint32_t *handle_p) { @@ -59,7 +60,7 @@ int virtio_gpu_gem_create(struct drm_file *file, int ret; u32 handle; - obj = virtio_gpu_alloc_object(dev, size, false, false); + obj = virtio_gpu_alloc_object(dev, params, NULL); if (IS_ERR(obj)) return PTR_ERR(obj); @@ -82,12 +83,10 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) { - struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_gem_object *gobj; - struct virtio_gpu_object *obj; + struct virtio_gpu_object_params params = { 0 }; int ret; uint32_t pitch; - uint32_t format; if (args->bpp != 32) return -EINVAL; @@ -96,22 +95,16 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, args->size = pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); - ret = virtio_gpu_gem_create(file_priv, dev, args->size, &gobj, + params.format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888); + params.width = args->width; + params.height = args->height; + params.size = args->size; + params.dumb = true; + ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj, &args->handle); if (ret) goto fail; - format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888); - obj = gem_to_virtio_gpu_obj(gobj); - virtio_gpu_cmd_create_resource(vgdev, obj, format, - args->width, args->height); - - /* attach the object to the resource */ - ret = virtio_gpu_object_attach(vgdev, obj, NULL); - if (ret) - goto fail; - - obj->dumb = true; args->pitch = pitch; return ret; diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 14ce8188c052..949a264985fc 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -54,8 +54,8 @@ static int virtio_gpu_map_ioctl(struct drm_device *dev, void *data, &virtio_gpu_map->offset); } -static int virtio_gpu_object_list_validate(struct ww_acquire_ctx *ticket, - struct list_head *head) +int virtio_gpu_object_list_validate(struct ww_acquire_ctx *ticket, + struct list_head *head) { struct ttm_operation_ctx ctx = { false, false }; struct ttm_validate_buffer *buf; @@ -79,7 +79,7 @@ static int virtio_gpu_object_list_validate(struct ww_acquire_ctx *ticket, return 0; } -static void virtio_gpu_unref_list(struct list_head *head) +void virtio_gpu_unref_list(struct list_head *head) { struct ttm_validate_buffer *buf; struct ttm_buffer_object *bo; @@ -275,16 +275,12 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, { struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_virtgpu_resource_create *rc = data; + struct virtio_gpu_fence *fence; int ret; struct virtio_gpu_object *qobj; struct drm_gem_object *obj; uint32_t handle = 0; - uint32_t size; - struct list_head validate_list; - struct ttm_validate_buffer mainbuf; - struct virtio_gpu_fence *fence = NULL; - struct ww_acquire_ctx ticket; - struct virtio_gpu_resource_create_3d rc_3d; + struct virtio_gpu_object_params params = { 0 }; if (vgdev->has_virgl_3d == false) { if (rc->depth > 1) @@ -299,94 +295,43 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - INIT_LIST_HEAD(&validate_list); - memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer)); - - size = rc->size; - + params.format = rc->format; + params.width = rc->width; + params.height = rc->height; + params.size = rc->size; + if (vgdev->has_virgl_3d) { + params.virgl = true; + params.target = rc->target; + params.bind = rc->bind; + params.depth = rc->depth; + params.array_size = rc->array_size; + params.last_level = rc->last_level; + params.nr_samples = rc->nr_samples; + params.flags = rc->flags; + } /* allocate a single page size object */ - if (size == 0) - size = PAGE_SIZE; + if (params.size == 0) + params.size = PAGE_SIZE; - qobj = virtio_gpu_alloc_object(dev, size, false, false); + fence = virtio_gpu_fence_alloc(vgdev); + if (!fence) + return -ENOMEM; + qobj = virtio_gpu_alloc_object(dev, ¶ms, fence); + dma_fence_put(&fence->f); if (IS_ERR(qobj)) return PTR_ERR(qobj); obj = &qobj->gem_base; - if (!vgdev->has_virgl_3d) { - virtio_gpu_cmd_create_resource(vgdev, qobj, rc->format, - rc->width, rc->height); - - ret = virtio_gpu_object_attach(vgdev, qobj, NULL); - } else { - /* use a gem reference since unref list undoes them */ - drm_gem_object_get(&qobj->gem_base); - mainbuf.bo = &qobj->tbo; - list_add(&mainbuf.head, &validate_list); - - ret = virtio_gpu_object_list_validate(&ticket, &validate_list); - if (ret) { - DRM_DEBUG("failed to validate\n"); - goto fail_unref; - } - - rc_3d.resource_id = cpu_to_le32(qobj->hw_res_handle); - rc_3d.target = cpu_to_le32(rc->target); - rc_3d.format = cpu_to_le32(rc->format); - rc_3d.bind = cpu_to_le32(rc->bind); - rc_3d.width = cpu_to_le32(rc->width); - rc_3d.height = cpu_to_le32(rc->height); - rc_3d.depth = cpu_to_le32(rc->depth); - rc_3d.array_size = cpu_to_le32(rc->array_size); - rc_3d.last_level = cpu_to_le32(rc->last_level); - rc_3d.nr_samples = cpu_to_le32(rc->nr_samples); - rc_3d.flags = cpu_to_le32(rc->flags); - - fence = virtio_gpu_fence_alloc(vgdev); - if (!fence) { - ret = -ENOMEM; - goto fail_backoff; - } - - virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); - ret = virtio_gpu_object_attach(vgdev, qobj, fence); - if (ret) { - dma_fence_put(&fence->f); - goto fail_backoff; - } - ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); - } - ret = drm_gem_handle_create(file_priv, obj, &handle); if (ret) { - drm_gem_object_release(obj); - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } return ret; } drm_gem_object_put_unlocked(obj); rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */ rc->bo_handle = handle; - - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } return 0; -fail_backoff: - ttm_eu_backoff_reservation(&ticket, &validate_list); -fail_unref: - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } -//fail_obj: -// drm_gem_object_handle_unreference_unlocked(obj); - return ret; } static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index e7e946035027..b2da31310d24 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -23,6 +23,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include <drm/ttm/ttm_execbuf_util.h> + #include "virtgpu_drv.h" static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, @@ -74,39 +76,34 @@ static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) kfree(bo); } -static void virtio_gpu_init_ttm_placement(struct virtio_gpu_object *vgbo, - bool pinned) +static void virtio_gpu_init_ttm_placement(struct virtio_gpu_object *vgbo) { u32 c = 1; - u32 pflag = pinned ? TTM_PL_FLAG_NO_EVICT : 0; vgbo->placement.placement = &vgbo->placement_code; vgbo->placement.busy_placement = &vgbo->placement_code; vgbo->placement_code.fpfn = 0; vgbo->placement_code.lpfn = 0; vgbo->placement_code.flags = - TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT | pflag; + TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT | + TTM_PL_FLAG_NO_EVICT; vgbo->placement.num_placement = c; vgbo->placement.num_busy_placement = c; } int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, - unsigned long size, bool kernel, bool pinned, - struct virtio_gpu_object **bo_ptr) + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr, + struct virtio_gpu_fence *fence) { struct virtio_gpu_object *bo; - enum ttm_bo_type type; size_t acc_size; int ret; - if (kernel) - type = ttm_bo_type_kernel; - else - type = ttm_bo_type_device; *bo_ptr = NULL; - acc_size = ttm_bo_dma_acc_size(&vgdev->mman.bdev, size, + acc_size = ttm_bo_dma_acc_size(&vgdev->mman.bdev, params->size, sizeof(struct virtio_gpu_object)); bo = kzalloc(sizeof(struct virtio_gpu_object), GFP_KERNEL); @@ -117,23 +114,62 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, kfree(bo); return ret; } - size = roundup(size, PAGE_SIZE); - ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size); + params->size = roundup(params->size, PAGE_SIZE); + ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, params->size); if (ret != 0) { virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); kfree(bo); return ret; } - bo->dumb = false; - virtio_gpu_init_ttm_placement(bo, pinned); + bo->dumb = params->dumb; + + if (params->virgl) { + virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, fence); + } else { + virtio_gpu_cmd_create_resource(vgdev, bo, params, fence); + } - ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, size, type, - &bo->placement, 0, !kernel, acc_size, - NULL, NULL, &virtio_gpu_ttm_bo_destroy); + virtio_gpu_init_ttm_placement(bo); + ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size, + ttm_bo_type_device, &bo->placement, 0, + true, acc_size, NULL, NULL, + &virtio_gpu_ttm_bo_destroy); /* ttm_bo_init failure will call the destroy */ if (ret != 0) return ret; + if (fence) { + struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; + struct list_head validate_list; + struct ttm_validate_buffer mainbuf; + struct ww_acquire_ctx ticket; + unsigned long irq_flags; + bool signaled; + + INIT_LIST_HEAD(&validate_list); + memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer)); + + /* use a gem reference since unref list undoes them */ + drm_gem_object_get(&bo->gem_base); + mainbuf.bo = &bo->tbo; + list_add(&mainbuf.head, &validate_list); + + ret = virtio_gpu_object_list_validate(&ticket, &validate_list); + if (ret == 0) { + spin_lock_irqsave(&drv->lock, irq_flags); + signaled = virtio_fence_signaled(&fence->f); + if (!signaled) + /* virtio create command still in flight */ + ttm_eu_fence_buffer_objects(&ticket, &validate_list, + &fence->f); + spin_unlock_irqrestore(&drv->lock, irq_flags); + if (signaled) + /* virtio create command finished */ + ttm_eu_backoff_reservation(&ticket, &validate_list); + } + virtio_gpu_unref_list(&validate_list); + } + *bo_ptr = bo; return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index c59ec34c80a5..22ef151410e0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -28,15 +28,16 @@ * device that might share buffers with virtgpu */ -int virtgpu_gem_prime_pin(struct drm_gem_object *obj) +struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) { - WARN_ONCE(1, "not implemented"); - return -ENODEV; -} + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); -void virtgpu_gem_prime_unpin(struct drm_gem_object *obj) -{ - WARN_ONCE(1, "not implemented"); + if (!bo->tbo.ttm->pages || !bo->tbo.ttm->num_pages) + /* should not happen */ + return ERR_PTR(-EINVAL); + + return drm_prime_pages_to_sg(bo->tbo.ttm->pages, + bo->tbo.ttm->num_pages); } void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj) @@ -56,7 +57,10 @@ void virtgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) } int virtgpu_gem_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *area) + struct vm_area_struct *vma) { - return -ENODEV; + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + + bo->gem_base.vma_node.vm_node.start = bo->tbo.vma_node.vm_node.start; + return drm_gem_prime_mmap(obj, vma); } diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c index d6225ba20b30..300ef3a83538 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ttm.c +++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c @@ -114,10 +114,6 @@ static const struct ttm_mem_type_manager_func virtio_gpu_bo_manager_func = { static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { - struct virtio_gpu_device *vgdev; - - vgdev = virtio_gpu_get_vgdev(bdev); - switch (type) { case TTM_PL_SYSTEM: /* System memory */ @@ -192,42 +188,45 @@ static void virtio_gpu_ttm_io_mem_free(struct ttm_bo_device *bdev, */ struct virtio_gpu_ttm_tt { struct ttm_dma_tt ttm; - struct virtio_gpu_device *vgdev; - u64 offset; + struct virtio_gpu_object *obj; }; -static int virtio_gpu_ttm_backend_bind(struct ttm_tt *ttm, - struct ttm_mem_reg *bo_mem) +static int virtio_gpu_ttm_tt_bind(struct ttm_tt *ttm, + struct ttm_mem_reg *bo_mem) { - struct virtio_gpu_ttm_tt *gtt = (void *)ttm; - - gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); - if (!ttm->num_pages) - WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", - ttm->num_pages, bo_mem, ttm); + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); + struct virtio_gpu_device *vgdev = + virtio_gpu_get_vgdev(gtt->obj->tbo.bdev); - /* Not implemented */ + virtio_gpu_object_attach(vgdev, gtt->obj, NULL); return 0; } -static int virtio_gpu_ttm_backend_unbind(struct ttm_tt *ttm) +static int virtio_gpu_ttm_tt_unbind(struct ttm_tt *ttm) { - /* Not implemented */ + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); + struct virtio_gpu_device *vgdev = + virtio_gpu_get_vgdev(gtt->obj->tbo.bdev); + + virtio_gpu_object_detach(vgdev, gtt->obj); return 0; } -static void virtio_gpu_ttm_backend_destroy(struct ttm_tt *ttm) +static void virtio_gpu_ttm_tt_destroy(struct ttm_tt *ttm) { - struct virtio_gpu_ttm_tt *gtt = (void *)ttm; + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); ttm_dma_tt_fini(>t->ttm); kfree(gtt); } -static struct ttm_backend_func virtio_gpu_backend_func = { - .bind = &virtio_gpu_ttm_backend_bind, - .unbind = &virtio_gpu_ttm_backend_unbind, - .destroy = &virtio_gpu_ttm_backend_destroy, +static struct ttm_backend_func virtio_gpu_tt_func = { + .bind = &virtio_gpu_ttm_tt_bind, + .unbind = &virtio_gpu_ttm_tt_unbind, + .destroy = &virtio_gpu_ttm_tt_destroy, }; static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, @@ -240,8 +239,8 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, gtt = kzalloc(sizeof(struct virtio_gpu_ttm_tt), GFP_KERNEL); if (gtt == NULL) return NULL; - gtt->ttm.ttm.func = &virtio_gpu_backend_func; - gtt->vgdev = vgdev; + gtt->ttm.ttm.func = &virtio_gpu_tt_func; + gtt->obj = container_of(bo, struct virtio_gpu_object, tbo); if (ttm_dma_tt_init(>t->ttm, bo, page_flags)) { kfree(gtt); return NULL; @@ -249,58 +248,11 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, return >t->ttm.ttm; } -static void virtio_gpu_move_null(struct ttm_buffer_object *bo, - struct ttm_mem_reg *new_mem) -{ - struct ttm_mem_reg *old_mem = &bo->mem; - - BUG_ON(old_mem->mm_node != NULL); - *old_mem = *new_mem; - new_mem->mm_node = NULL; -} - -static int virtio_gpu_bo_move(struct ttm_buffer_object *bo, bool evict, - struct ttm_operation_ctx *ctx, - struct ttm_mem_reg *new_mem) -{ - int ret; - - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); - if (ret) - return ret; - - virtio_gpu_move_null(bo, new_mem); - return 0; -} - -static void virtio_gpu_bo_move_notify(struct ttm_buffer_object *tbo, - bool evict, - struct ttm_mem_reg *new_mem) -{ - struct virtio_gpu_object *bo; - struct virtio_gpu_device *vgdev; - - bo = container_of(tbo, struct virtio_gpu_object, tbo); - vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; - - if (!new_mem || (new_mem->placement & TTM_PL_FLAG_SYSTEM)) { - if (bo->hw_res_handle) - virtio_gpu_object_detach(vgdev, bo); - - } else if (new_mem->placement & TTM_PL_FLAG_TT) { - if (bo->hw_res_handle) { - virtio_gpu_object_attach(vgdev, bo, NULL); - } - } -} - static void virtio_gpu_bo_swap_notify(struct ttm_buffer_object *tbo) { struct virtio_gpu_object *bo; - struct virtio_gpu_device *vgdev; bo = container_of(tbo, struct virtio_gpu_object, tbo); - vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; if (bo->pages) virtio_gpu_object_free_sg_table(bo); @@ -312,11 +264,9 @@ static struct ttm_bo_driver virtio_gpu_bo_driver = { .init_mem_type = &virtio_gpu_init_mem_type, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = &virtio_gpu_evict_flags, - .move = &virtio_gpu_bo_move, .verify_access = &virtio_gpu_verify_access, .io_mem_reserve = &virtio_gpu_ttm_io_mem_reserve, .io_mem_free = &virtio_gpu_ttm_io_mem_free, - .move_notify = &virtio_gpu_bo_move_notify, .swap_notify = &virtio_gpu_bo_swap_notify, }; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 6bc2008b0d0d..e62fe24b1a2e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -376,9 +376,8 @@ retry: /* create a basic resource */ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - uint32_t format, - uint32_t width, - uint32_t height) + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence) { struct virtio_gpu_resource_create_2d *cmd_p; struct virtio_gpu_vbuffer *vbuf; @@ -388,11 +387,11 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_2D); cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); - cmd_p->format = cpu_to_le32(format); - cmd_p->width = cpu_to_le32(width); - cmd_p->height = cpu_to_le32(height); + cmd_p->format = cpu_to_le32(params->format); + cmd_p->width = cpu_to_le32(params->width); + cmd_p->height = cpu_to_le32(params->height); - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, &cmd_p->hdr, fence); bo->created = true; } @@ -828,7 +827,8 @@ void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - struct virtio_gpu_resource_create_3d *rc_3d) + struct virtio_gpu_object_params *params, + struct virtio_gpu_fence *fence) { struct virtio_gpu_resource_create_3d *cmd_p; struct virtio_gpu_vbuffer *vbuf; @@ -836,11 +836,21 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); - *cmd_p = *rc_3d; cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_3D); - cmd_p->hdr.flags = 0; + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + cmd_p->format = cpu_to_le32(params->format); + cmd_p->width = cpu_to_le32(params->width); + cmd_p->height = cpu_to_le32(params->height); + + cmd_p->target = cpu_to_le32(params->target); + cmd_p->bind = cpu_to_le32(params->bind); + cmd_p->depth = cpu_to_le32(params->depth); + cmd_p->array_size = cpu_to_le32(params->array_size); + cmd_p->last_level = cpu_to_le32(params->last_level); + cmd_p->nr_samples = cpu_to_le32(params->nr_samples); + cmd_p->flags = cpu_to_le32(params->flags); - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, &cmd_p->hdr, fence); bo->created = true; } @@ -924,8 +934,8 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, struct scatterlist *sg; int si, nents; - if (!obj->created) - return 0; + if (WARN_ON_ONCE(!obj->created)) + return -EINVAL; if (!obj->pages) { int ret; |