Commit bfa3357e authored by Christian König's avatar Christian König
Browse files

drm/ttm: allocate resource object instead of embedding it v2



To improve the handling we want the establish the resource object as base
class for the backend allocations.

v2: add missing error handling

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210602100914.46246-1-christian.koenig@amd.com
parent 4e566003
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -362,14 +362,14 @@ int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev,
	if (cpu_addr)
	if (cpu_addr)
		amdgpu_bo_kunmap(*bo_ptr);
		amdgpu_bo_kunmap(*bo_ptr);


	ttm_resource_free(&(*bo_ptr)->tbo, (*bo_ptr)->tbo.resource);
	ttm_resource_free(&(*bo_ptr)->tbo, &(*bo_ptr)->tbo.resource);


	for (i = 0; i < (*bo_ptr)->placement.num_placement; ++i) {
	for (i = 0; i < (*bo_ptr)->placement.num_placement; ++i) {
		(*bo_ptr)->placements[i].fpfn = offset >> PAGE_SHIFT;
		(*bo_ptr)->placements[i].fpfn = offset >> PAGE_SHIFT;
		(*bo_ptr)->placements[i].lpfn = (offset + size) >> PAGE_SHIFT;
		(*bo_ptr)->placements[i].lpfn = (offset + size) >> PAGE_SHIFT;
	}
	}
	r = ttm_bo_mem_space(&(*bo_ptr)->tbo, &(*bo_ptr)->placement,
	r = ttm_bo_mem_space(&(*bo_ptr)->tbo, &(*bo_ptr)->placement,
			     (*bo_ptr)->tbo.resource, &ctx);
			     &(*bo_ptr)->tbo.resource, &ctx);
	if (r)
	if (r)
		goto error;
		goto error;


+27 −27
Original line number Original line Diff line number Diff line
@@ -491,7 +491,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
			return r;
			return r;


		amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
		amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
		ttm_resource_free(bo, bo->resource);
		ttm_resource_free(bo, &bo->resource);
		ttm_bo_assign_mem(bo, new_mem);
		ttm_bo_assign_mem(bo, new_mem);
		goto out;
		goto out;
	}
	}
@@ -950,9 +950,9 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
	struct ttm_operation_ctx ctx = { false, false };
	struct ttm_operation_ctx ctx = { false, false };
	struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
	struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
	struct ttm_resource tmp;
	struct ttm_placement placement;
	struct ttm_placement placement;
	struct ttm_place placements;
	struct ttm_place placements;
	struct ttm_resource *tmp;
	uint64_t addr, flags;
	uint64_t addr, flags;
	int r;
	int r;


@@ -962,7 +962,8 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
	addr = amdgpu_gmc_agp_addr(bo);
	addr = amdgpu_gmc_agp_addr(bo);
	if (addr != AMDGPU_BO_INVALID_OFFSET) {
	if (addr != AMDGPU_BO_INVALID_OFFSET) {
		bo->resource->start = addr >> PAGE_SHIFT;
		bo->resource->start = addr >> PAGE_SHIFT;
	} else {
		return 0;
	}


	/* allocate GART space */
	/* allocate GART space */
	placement.num_placement = 1;
	placement.num_placement = 1;
@@ -979,19 +980,18 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
		return r;
		return r;


	/* compute PTE flags for this buffer object */
	/* compute PTE flags for this buffer object */
		flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp);
	flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, tmp);


	/* Bind pages */
	/* Bind pages */
		gtt->offset = (u64)tmp.start << PAGE_SHIFT;
	gtt->offset = (u64)tmp->start << PAGE_SHIFT;
	r = amdgpu_ttm_gart_bind(adev, bo, flags);
	r = amdgpu_ttm_gart_bind(adev, bo, flags);
	if (unlikely(r)) {
	if (unlikely(r)) {
		ttm_resource_free(bo, &tmp);
		ttm_resource_free(bo, &tmp);
		return r;
		return r;
	}
	}


		ttm_resource_free(bo, bo->resource);
	ttm_resource_free(bo, &bo->resource);
		ttm_bo_assign_mem(bo, &tmp);
	ttm_bo_assign_mem(bo, tmp);
	}


	return 0;
	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -1009,7 +1009,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict,
	if (old_reg->mem_type == TTM_PL_TT &&
	if (old_reg->mem_type == TTM_PL_TT &&
	    new_reg->mem_type == TTM_PL_SYSTEM) {
	    new_reg->mem_type == TTM_PL_SYSTEM) {
		nouveau_ttm_tt_unbind(bo->bdev, bo->ttm);
		nouveau_ttm_tt_unbind(bo->bdev, bo->ttm);
		ttm_resource_free(bo, bo->resource);
		ttm_resource_free(bo, &bo->resource);
		ttm_bo_assign_mem(bo, new_reg);
		ttm_bo_assign_mem(bo, new_reg);
		goto out;
		goto out;
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -229,7 +229,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
	if (old_mem->mem_type == TTM_PL_TT &&
	if (old_mem->mem_type == TTM_PL_TT &&
	    new_mem->mem_type == TTM_PL_SYSTEM) {
	    new_mem->mem_type == TTM_PL_SYSTEM) {
		radeon_ttm_tt_unbind(bo->bdev, bo->ttm);
		radeon_ttm_tt_unbind(bo->bdev, bo->ttm);
		ttm_resource_free(bo, bo->resource);
		ttm_resource_free(bo, &bo->resource);
		ttm_bo_assign_mem(bo, new_mem);
		ttm_bo_assign_mem(bo, new_mem);
		goto out;
		goto out;
	}
	}
+28 −55
Original line number Original line Diff line number Diff line
@@ -223,7 +223,7 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
		bo->bdev->funcs->delete_mem_notify(bo);
		bo->bdev->funcs->delete_mem_notify(bo);


	ttm_bo_tt_destroy(bo);
	ttm_bo_tt_destroy(bo);
	ttm_resource_free(bo, bo->resource);
	ttm_resource_free(bo, &bo->resource);
}
}


static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
@@ -489,7 +489,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo,
			struct ttm_operation_ctx *ctx)
			struct ttm_operation_ctx *ctx)
{
{
	struct ttm_device *bdev = bo->bdev;
	struct ttm_device *bdev = bo->bdev;
	struct ttm_resource evict_mem;
	struct ttm_resource *evict_mem;
	struct ttm_placement placement;
	struct ttm_placement placement;
	struct ttm_place hop;
	struct ttm_place hop;
	int ret = 0;
	int ret = 0;
@@ -519,7 +519,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo,
		goto out;
		goto out;
	}
	}


	ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, ctx, &hop);
	ret = ttm_bo_handle_move_mem(bo, evict_mem, true, ctx, &hop);
	if (unlikely(ret)) {
	if (unlikely(ret)) {
		WARN(ret == -EMULTIHOP, "Unexpected multihop in eviction - likely driver bug\n");
		WARN(ret == -EMULTIHOP, "Unexpected multihop in eviction - likely driver bug\n");
		if (ret != -ERESTARTSYS)
		if (ret != -ERESTARTSYS)
@@ -728,14 +728,15 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
 */
 */
static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
				  const struct ttm_place *place,
				  const struct ttm_place *place,
				  struct ttm_resource *mem,
				  struct ttm_resource **mem,
				  struct ttm_operation_ctx *ctx)
				  struct ttm_operation_ctx *ctx)
{
{
	struct ttm_device *bdev = bo->bdev;
	struct ttm_device *bdev = bo->bdev;
	struct ttm_resource_manager *man = ttm_manager_type(bdev, mem->mem_type);
	struct ttm_resource_manager *man;
	struct ww_acquire_ctx *ticket;
	struct ww_acquire_ctx *ticket;
	int ret;
	int ret;


	man = ttm_manager_type(bdev, (*mem)->mem_type);
	ticket = dma_resv_locking_ctx(bo->base.resv);
	ticket = dma_resv_locking_ctx(bo->base.resv);
	do {
	do {
		ret = ttm_resource_alloc(bo, place, mem);
		ret = ttm_resource_alloc(bo, place, mem);
@@ -749,37 +750,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
			return ret;
			return ret;
	} while (1);
	} while (1);


	return ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
	return ttm_bo_add_move_fence(bo, man, *mem, ctx->no_wait_gpu);
}

/**
 * ttm_bo_mem_placement - check if placement is compatible
 * @bo: BO to find memory for
 * @place: where to search
 * @mem: the memory object to fill in
 *
 * Check if placement is compatible and fill in mem structure.
 * Returns -EBUSY if placement won't work or negative error code.
 * 0 when placement can be used.
 */
static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,
				const struct ttm_place *place,
				struct ttm_resource *mem)
{
	struct ttm_device *bdev = bo->bdev;
	struct ttm_resource_manager *man;

	man = ttm_manager_type(bdev, place->mem_type);
	if (!man || !ttm_resource_manager_used(man))
		return -EBUSY;

	mem->mem_type = place->mem_type;
	mem->placement = place->flags;

	spin_lock(&bo->bdev->lru_lock);
	ttm_bo_move_to_lru_tail(bo, mem, NULL);
	spin_unlock(&bo->bdev->lru_lock);
	return 0;
}
}


/*
/*
@@ -792,7 +763,7 @@ static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,
 */
 */
int ttm_bo_mem_space(struct ttm_buffer_object *bo,
int ttm_bo_mem_space(struct ttm_buffer_object *bo,
			struct ttm_placement *placement,
			struct ttm_placement *placement,
			struct ttm_resource *mem,
			struct ttm_resource **mem,
			struct ttm_operation_ctx *ctx)
			struct ttm_operation_ctx *ctx)
{
{
	struct ttm_device *bdev = bo->bdev;
	struct ttm_device *bdev = bo->bdev;
@@ -807,8 +778,8 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
		const struct ttm_place *place = &placement->placement[i];
		const struct ttm_place *place = &placement->placement[i];
		struct ttm_resource_manager *man;
		struct ttm_resource_manager *man;


		ret = ttm_bo_mem_placement(bo, place, mem);
		man = ttm_manager_type(bdev, place->mem_type);
		if (ret)
		if (!man || !ttm_resource_manager_used(man))
			continue;
			continue;


		type_found = true;
		type_found = true;
@@ -818,8 +789,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
		if (unlikely(ret))
		if (unlikely(ret))
			goto error;
			goto error;


		man = ttm_manager_type(bdev, mem->mem_type);
		ret = ttm_bo_add_move_fence(bo, man, *mem, ctx->no_wait_gpu);
		ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
		if (unlikely(ret)) {
		if (unlikely(ret)) {
			ttm_resource_free(bo, mem);
			ttm_resource_free(bo, mem);
			if (ret == -EBUSY)
			if (ret == -EBUSY)
@@ -832,9 +802,10 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,


	for (i = 0; i < placement->num_busy_placement; ++i) {
	for (i = 0; i < placement->num_busy_placement; ++i) {
		const struct ttm_place *place = &placement->busy_placement[i];
		const struct ttm_place *place = &placement->busy_placement[i];
		struct ttm_resource_manager *man;


		ret = ttm_bo_mem_placement(bo, place, mem);
		man = ttm_manager_type(bdev, place->mem_type);
		if (ret)
		if (!man || !ttm_resource_manager_used(man))
			continue;
			continue;


		type_found = true;
		type_found = true;
@@ -861,12 +832,12 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
EXPORT_SYMBOL(ttm_bo_mem_space);
EXPORT_SYMBOL(ttm_bo_mem_space);


static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo,
static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo,
				     struct ttm_resource *mem,
				     struct ttm_resource **mem,
				     struct ttm_operation_ctx *ctx,
				     struct ttm_operation_ctx *ctx,
				     struct ttm_place *hop)
				     struct ttm_place *hop)
{
{
	struct ttm_placement hop_placement;
	struct ttm_placement hop_placement;
	struct ttm_resource hop_mem;
	struct ttm_resource *hop_mem;
	int ret;
	int ret;


	hop_placement.num_placement = hop_placement.num_busy_placement = 1;
	hop_placement.num_placement = hop_placement.num_busy_placement = 1;
@@ -877,7 +848,7 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo,
	if (ret)
	if (ret)
		return ret;
		return ret;
	/* move to the bounce domain */
	/* move to the bounce domain */
	ret = ttm_bo_handle_move_mem(bo, &hop_mem, false, ctx, NULL);
	ret = ttm_bo_handle_move_mem(bo, hop_mem, false, ctx, NULL);
	if (ret) {
	if (ret) {
		ttm_resource_free(bo, &hop_mem);
		ttm_resource_free(bo, &hop_mem);
		return ret;
		return ret;
@@ -889,14 +860,12 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
			      struct ttm_placement *placement,
			      struct ttm_placement *placement,
			      struct ttm_operation_ctx *ctx)
			      struct ttm_operation_ctx *ctx)
{
{
	struct ttm_resource *mem;
	struct ttm_place hop;
	struct ttm_place hop;
	struct ttm_resource mem;
	int ret;
	int ret;


	dma_resv_assert_held(bo->base.resv);
	dma_resv_assert_held(bo->base.resv);


	memset(&hop, 0, sizeof(hop));

	/*
	/*
	 * Determine where to move the buffer.
	 * Determine where to move the buffer.
	 *
	 *
@@ -910,7 +879,7 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
	if (ret)
	if (ret)
		return ret;
		return ret;
bounce:
bounce:
	ret = ttm_bo_handle_move_mem(bo, &mem, false, ctx, &hop);
	ret = ttm_bo_handle_move_mem(bo, mem, false, ctx, &hop);
	if (ret == -EMULTIHOP) {
	if (ret == -EMULTIHOP) {
		ret = ttm_bo_bounce_temp_buffer(bo, &mem, ctx, &hop);
		ret = ttm_bo_bounce_temp_buffer(bo, &mem, ctx, &hop);
		if (ret)
		if (ret)
@@ -1019,7 +988,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
{
{
	static const struct ttm_place sys_mem = { .mem_type = TTM_PL_SYSTEM };
	static const struct ttm_place sys_mem = { .mem_type = TTM_PL_SYSTEM };
	bool locked;
	bool locked;
	int ret = 0;
	int ret;


	bo->destroy = destroy ? destroy : ttm_bo_default_destroy;
	bo->destroy = destroy ? destroy : ttm_bo_default_destroy;


@@ -1029,8 +998,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
	bo->bdev = bdev;
	bo->bdev = bdev;
	bo->type = type;
	bo->type = type;
	bo->page_alignment = page_alignment;
	bo->page_alignment = page_alignment;
	bo->resource = &bo->_mem;
	ttm_resource_alloc(bo, &sys_mem, bo->resource);
	bo->moving = NULL;
	bo->moving = NULL;
	bo->pin_count = 0;
	bo->pin_count = 0;
	bo->sg = sg;
	bo->sg = sg;
@@ -1042,6 +1009,12 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
	}
	}
	atomic_inc(&ttm_glob.bo_count);
	atomic_inc(&ttm_glob.bo_count);


	ret = ttm_resource_alloc(bo, &sys_mem, &bo->resource);
	if (unlikely(ret)) {
		ttm_bo_put(bo);
		return ret;
	}

	/*
	/*
	 * For ttm_bo_type_device buffers, allocate
	 * For ttm_bo_type_device buffers, allocate
	 * address space from the device.
	 * address space from the device.
@@ -1170,7 +1143,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
	 */
	 */
	if (bo->resource->mem_type != TTM_PL_SYSTEM) {
	if (bo->resource->mem_type != TTM_PL_SYSTEM) {
		struct ttm_operation_ctx ctx = { false, false };
		struct ttm_operation_ctx ctx = { false, false };
		struct ttm_resource evict_mem;
		struct ttm_resource *evict_mem;
		struct ttm_place place, hop;
		struct ttm_place place, hop;


		memset(&place, 0, sizeof(place));
		memset(&place, 0, sizeof(place));
@@ -1182,7 +1155,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx,
		if (unlikely(ret))
		if (unlikely(ret))
			goto out;
			goto out;


		ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, &ctx, &hop);
		ret = ttm_bo_handle_move_mem(bo, evict_mem, true, &ctx, &hop);
		if (unlikely(ret != 0)) {
		if (unlikely(ret != 0)) {
			WARN(ret == -EMULTIHOP, "Unexpected multihop in swaput - likely driver bug.\n");
			WARN(ret == -EMULTIHOP, "Unexpected multihop in swaput - likely driver bug.\n");
			goto out;
			goto out;
Loading