Commit 5452cf44 authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/ttm: keep a reference to transfer pipelined BOs



Make sure the transfered BO is never destroy before the transfer BO.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarRoger He <Hongbo.He@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 89a11147
Loading
Loading
Loading
Loading
+30 −20
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@
#include <linux/module.h>
#include <linux/reservation.h>

struct ttm_transfer_obj {
	struct ttm_buffer_object base;
	struct ttm_buffer_object *bo;
};

void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
{
	ttm_bo_mem_put(bo, &bo->mem);
@@ -454,7 +459,11 @@ EXPORT_SYMBOL(ttm_bo_move_memcpy);

static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
{
	kfree(bo);
	struct ttm_transfer_obj *fbo;

	fbo = container_of(bo, struct ttm_transfer_obj, base);
	ttm_bo_unref(&fbo->bo);
	kfree(fbo);
}

/**
@@ -475,14 +484,15 @@ static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
				      struct ttm_buffer_object **new_obj)
{
	struct ttm_buffer_object *fbo;
	struct ttm_transfer_obj *fbo;
	int ret;

	fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
	if (!fbo)
		return -ENOMEM;

	*fbo = *bo;
	fbo->base = *bo;
	fbo->bo = ttm_bo_reference(bo);

	/**
	 * Fix up members that we shouldn't copy directly:
@@ -490,25 +500,25 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
	 */

	atomic_inc(&bo->bdev->glob->bo_count);
	INIT_LIST_HEAD(&fbo->ddestroy);
	INIT_LIST_HEAD(&fbo->lru);
	INIT_LIST_HEAD(&fbo->swap);
	INIT_LIST_HEAD(&fbo->io_reserve_lru);
	mutex_init(&fbo->wu_mutex);
	fbo->moving = NULL;
	drm_vma_node_reset(&fbo->vma_node);
	atomic_set(&fbo->cpu_writers, 0);

	kref_init(&fbo->list_kref);
	kref_init(&fbo->kref);
	fbo->destroy = &ttm_transfered_destroy;
	fbo->acc_size = 0;
	fbo->resv = &fbo->ttm_resv;
	reservation_object_init(fbo->resv);
	ret = reservation_object_trylock(fbo->resv);
	INIT_LIST_HEAD(&fbo->base.ddestroy);
	INIT_LIST_HEAD(&fbo->base.lru);
	INIT_LIST_HEAD(&fbo->base.swap);
	INIT_LIST_HEAD(&fbo->base.io_reserve_lru);
	mutex_init(&fbo->base.wu_mutex);
	fbo->base.moving = NULL;
	drm_vma_node_reset(&fbo->base.vma_node);
	atomic_set(&fbo->base.cpu_writers, 0);

	kref_init(&fbo->base.list_kref);
	kref_init(&fbo->base.kref);
	fbo->base.destroy = &ttm_transfered_destroy;
	fbo->base.acc_size = 0;
	fbo->base.resv = &fbo->base.ttm_resv;
	reservation_object_init(fbo->base.resv);
	ret = reservation_object_trylock(fbo->base.resv);
	WARN_ON(!ret);

	*new_obj = fbo;
	*new_obj = &fbo->base;
	return 0;
}