drm/virtio: rework virtio_gpu_object_create fencing

Rework fencing workflow.  Stop using ttm helpers, use the
virtio_gpu_array_* helpers instead.

Due to using the gem reservation object it is initialized and ready for
use before calling ttm_bo_init.  So we can simply use the standard
fencing workflow and drop the tricky logic which checks whenever the
command is in flight still.

v6: rewrite most of the patch.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20190829103301.3539-10-kraxel@redhat.com
This commit is contained in:
Gerd Hoffmann
2019-08-29 12:32:52 +02:00
parent da758d5196
commit e2324300f4
3 changed files with 37 additions and 43 deletions

View File

@@ -103,6 +103,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object **bo_ptr,
struct virtio_gpu_fence *fence)
{
struct virtio_gpu_object_array *objs = NULL;
struct virtio_gpu_object *bo;
size_t acc_size;
int ret;
@@ -116,23 +117,34 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
if (bo == NULL)
return -ENOMEM;
ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle);
if (ret < 0) {
kfree(bo);
return ret;
}
if (ret < 0)
goto err_free_gem;
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;
}
if (ret != 0)
goto err_put_id;
bo->dumb = params->dumb;
if (fence) {
ret = -ENOMEM;
objs = virtio_gpu_array_alloc(1);
if (!objs)
goto err_put_id;
virtio_gpu_array_add_obj(objs, &bo->gem_base);
ret = virtio_gpu_array_lock_resv(objs);
if (ret != 0)
goto err_put_objs;
}
if (params->virgl) {
virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, fence);
virtio_gpu_cmd_resource_create_3d(vgdev, bo, params,
objs, fence);
} else {
virtio_gpu_cmd_create_resource(vgdev, bo, params, fence);
virtio_gpu_cmd_create_resource(vgdev, bo, params,
objs, fence);
}
virtio_gpu_init_ttm_placement(bo);
@@ -145,40 +157,16 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
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;
err_put_objs:
virtio_gpu_array_put_free(objs);
err_put_id:
virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
err_free_gem:
kfree(bo);
return ret;
}
void virtio_gpu_object_kunmap(struct virtio_gpu_object *bo)