diff options
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_object.c')
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_object.c | 26 | 
1 files changed, 25 insertions, 1 deletions
| diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index eca765537470..f39a183d59c2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -25,6 +25,23 @@  #include "virtgpu_drv.h" +static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, +				       uint32_t *resid) +{ +	int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); + +	if (handle < 0) +		return handle; + +	*resid = handle + 1; +	return 0; +} + +static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) +{ +	ida_free(&vgdev->resource_ida, id - 1); +} +  static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)  {  	struct virtio_gpu_object *bo; @@ -33,13 +50,14 @@ static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)  	bo = container_of(tbo, struct virtio_gpu_object, tbo);  	vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; -	if (bo->hw_res_handle) +	if (bo->created)  		virtio_gpu_cmd_unref_resource(vgdev, bo->hw_res_handle);  	if (bo->pages)  		virtio_gpu_object_free_sg_table(bo);  	if (bo->vmap)  		virtio_gpu_object_kunmap(bo);  	drm_gem_object_release(&bo->gem_base); +	virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);  	kfree(bo);  } @@ -81,9 +99,15 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,  	bo = kzalloc(sizeof(struct virtio_gpu_object), GFP_KERNEL);  	if (bo == NULL)  		return -ENOMEM; +	ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle); +	if (ret < 0) { +		kfree(bo); +		return ret; +	}  	size = roundup(size, PAGE_SIZE);  	ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size);  	if (ret != 0) { +		virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);  		kfree(bo);  		return ret;  	} | 
