drm/virtio: fix resource id handling
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 19 Oct 2018 06:18:47 +0000 (08:18 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 29 Oct 2018 21:50:55 +0000 (22:50 +0100)
Move virtio_gpu_resource_id_{get,put} to virtgpu_object.c and make them
static.  Allocate and free the id on creation and destroy, drop all
other calls.  That way objects have a valid handle for the whole
lifetime of the object.

Also fixes ids leaking.  Worst offender are dumb buffers, and I think
some error paths too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20181019061847.18958-7-kraxel@redhat.com
drivers/gpu/drm/virtio/virtgpu_drv.h
drivers/gpu/drm/virtio/virtgpu_fb.c
drivers/gpu/drm/virtio/virtgpu_gem.c
drivers/gpu/drm/virtio/virtgpu_ioctl.c
drivers/gpu/drm/virtio/virtgpu_object.c
drivers/gpu/drm/virtio/virtgpu_vq.c

index c6b0a938bac50fe4251ceac0fb19f24d72119a4f..78ad8f58edff0ef06cf2551d3d5f73b6dc8e368b 100644 (file)
@@ -260,9 +260,6 @@ int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb,
 /* virtio vg */
 int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
 void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
-void virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev,
-                              uint32_t *resid);
-void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id);
 void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
                                    struct virtio_gpu_object *bo,
                                    uint32_t format,
index c22a8246b62d397030042f3c563e0c9ee1724715..fb1cc8b2f119d9aadd794583c500f9715c1525fa 100644 (file)
@@ -231,7 +231,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper,
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
-       virtio_gpu_resource_id_get(vgdev, &obj->hw_res_handle);
        virtio_gpu_cmd_create_resource(vgdev, obj, format,
                                       mode_cmd.width, mode_cmd.height);
 
index 665d18a49d4226cc087f2f521aba6c3cffc497cb..f0658639397475f40800622091aef258ce759139 100644 (file)
@@ -103,7 +103,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
 
        format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888);
        obj = gem_to_virtio_gpu_obj(gobj);
-       virtio_gpu_resource_id_get(vgdev, &obj->hw_res_handle);
        virtio_gpu_cmd_create_resource(vgdev, obj, format,
                                       args->width, args->height);
 
index 6179d93167639b60f18bb95ee1631fb78b7f0f77..bc5afa4f906edf9ce9a2132ef052a14029bb2f56 100644 (file)
@@ -253,7 +253,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
        if (IS_ERR(qobj))
                return PTR_ERR(qobj);
        obj = &qobj->gem_base;
-       virtio_gpu_resource_id_get(vgdev, &qobj->hw_res_handle);
 
        if (!vgdev->has_virgl_3d) {
                virtio_gpu_cmd_create_resource(vgdev, qobj, rc->format,
index 6611c487d79807da0a459741aecdf2fe2dd07684..8bd1ebe13b623832ff3ecc01086a618586f1904f 100644 (file)
 
 #include "virtgpu_drv.h"
 
+static void virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev,
+                                      uint32_t *resid)
+{
+       int handle;
+
+       idr_preload(GFP_KERNEL);
+       spin_lock(&vgdev->resource_idr_lock);
+       handle = idr_alloc(&vgdev->resource_idr, NULL, 1, 0, GFP_NOWAIT);
+       spin_unlock(&vgdev->resource_idr_lock);
+       idr_preload_end();
+       *resid = handle;
+}
+
+static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id)
+{
+       spin_lock(&vgdev->resource_idr_lock);
+       idr_remove(&vgdev->resource_idr, id);
+       spin_unlock(&vgdev->resource_idr_lock);
+}
+
 static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
 {
        struct virtio_gpu_object *bo;
@@ -40,6 +60,7 @@ static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
        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 +102,11 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
        bo = kzalloc(sizeof(struct virtio_gpu_object), GFP_KERNEL);
        if (bo == NULL)
                return -ENOMEM;
+       virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle);
        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;
        }
index ea3d13793d600d874df473e18a1b13d04f3ed66c..d2861da2bbc9445aebca01733d0ef5babb7ecb4f 100644 (file)
                               + MAX_INLINE_CMD_SIZE             \
                               + MAX_INLINE_RESP_SIZE)
 
-void virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev,
-                               uint32_t *resid)
-{
-       int handle;
-
-       idr_preload(GFP_KERNEL);
-       spin_lock(&vgdev->resource_idr_lock);
-       handle = idr_alloc(&vgdev->resource_idr, NULL, 1, 0, GFP_NOWAIT);
-       spin_unlock(&vgdev->resource_idr_lock);
-       idr_preload_end();
-       *resid = handle;
-}
-
-void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id)
-{
-       spin_lock(&vgdev->resource_idr_lock);
-       idr_remove(&vgdev->resource_idr, id);
-       spin_unlock(&vgdev->resource_idr_lock);
-}
-
 void virtio_gpu_ctrl_ack(struct virtqueue *vq)
 {
        struct drm_device *dev = vq->vdev->priv;