From: Ray Strode <rstr...@redhat.com>

qxl_cursor_atomic_update allocs a bo for the cursor that
it never frees up at the end of the function.

This commit fixes that.

Signed-off-by: Ray Strode <rstr...@redhat.com>
---
 drivers/gpu/drm/qxl/qxl_display.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 4756b3c9bf2c..7335d99244d5 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -548,61 +548,61 @@ static void qxl_primary_atomic_disable(struct drm_plane 
*plane,
        struct qxl_device *qdev = plane->dev->dev_private;
 
        if (old_state->fb) {
                struct qxl_framebuffer *qfb =
                        to_qxl_framebuffer(old_state->fb);
                struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
 
                if (bo->is_primary) {
                        qxl_io_destroy_primary(qdev);
                        bo->is_primary = false;
                }
        }
 }
 
 static int qxl_plane_atomic_check(struct drm_plane *plane,
                                  struct drm_plane_state *state)
 {
        return 0;
 }
 
 static void qxl_cursor_atomic_update(struct drm_plane *plane,
                                     struct drm_plane_state *old_state)
 {
        struct drm_device *dev = plane->dev;
        struct qxl_device *qdev = dev->dev_private;
        struct drm_framebuffer *fb = plane->state->fb;
        struct qxl_release *release;
        struct qxl_cursor_cmd *cmd;
        struct qxl_cursor *cursor;
        struct drm_gem_object *obj;
-       struct qxl_bo *cursor_bo, *user_bo = NULL;
+       struct qxl_bo *cursor_bo = NULL, *user_bo = NULL;
        int ret;
        void *user_ptr;
        int size = 64*64*4;
 
        ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
                                         QXL_RELEASE_CURSOR_CMD,
                                         &release, NULL);
        if (ret)
                return;
 
        if (fb != old_state->fb) {
                obj = to_qxl_framebuffer(fb)->obj;
                user_bo = gem_to_qxl_bo(obj);
 
                /* pinning is done in the prepare/cleanup framevbuffer */
                ret = qxl_bo_kmap(user_bo, &user_ptr);
                if (ret)
                        goto out_free_release;
 
                ret = qxl_alloc_bo_reserved(qdev, release,
                                            sizeof(struct qxl_cursor) + size,
                                            &cursor_bo);
                if (ret)
                        goto out_kunmap;
 
                ret = qxl_release_reserve_list(release, true);
                if (ret)
                        goto out_free_bo;
 
                ret = qxl_bo_kmap(cursor_bo, (void **)&cursor);
@@ -618,60 +618,62 @@ static void qxl_cursor_atomic_update(struct drm_plane 
*plane,
                cursor->data_size = size;
                cursor->chunk.next_chunk = 0;
                cursor->chunk.prev_chunk = 0;
                cursor->chunk.data_size = size;
                memcpy(cursor->chunk.data, user_ptr, size);
                qxl_bo_kunmap(cursor_bo);
                qxl_bo_kunmap(user_bo);
 
                cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release);
                cmd->u.set.visible = 1;
                cmd->u.set.shape = qxl_bo_physical_address(qdev,
                                                           cursor_bo, 0);
                cmd->type = QXL_CURSOR_SET;
        } else {
 
                ret = qxl_release_reserve_list(release, true);
                if (ret)
                        goto out_free_release;
 
                cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release);
                cmd->type = QXL_CURSOR_MOVE;
        }
 
        cmd->u.position.x = plane->state->crtc_x + fb->hot_x;
        cmd->u.position.y = plane->state->crtc_y + fb->hot_y;
 
        qxl_release_unmap(qdev, release, &cmd->release_info);
        qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
        qxl_release_fence_buffer_objects(release);
 
+       qxl_bo_unref(&cursor_bo);
+
        return;
 
 out_backoff:
        qxl_release_backoff_reserve_list(release);
 out_free_bo:
        qxl_bo_unref(&cursor_bo);
 out_kunmap:
        qxl_bo_kunmap(user_bo);
 out_free_release:
        qxl_release_free(qdev, release);
        return;
 
 }
 
 static void qxl_cursor_atomic_disable(struct drm_plane *plane,
                                      struct drm_plane_state *old_state)
 {
        struct qxl_device *qdev = plane->dev->dev_private;
        struct qxl_release *release;
        struct qxl_cursor_cmd *cmd;
        int ret;
 
        ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
                                         QXL_RELEASE_CURSOR_CMD,
                                         &release, NULL);
        if (ret)
                return;
 
        ret = qxl_release_reserve_list(release, true);
        if (ret) {
-- 
2.14.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to