Commit 4c5ac948 authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/ttm: cleanup ttm_bo_mem_space



We tried this once before, but that turned out to be more
complicated than thought. With all the right prerequisites
it looks like we can do this now.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarChunming Zhou <david1.zhou@amd.com>
Tested-by: default avatarPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent af1dac01
Loading
Loading
Loading
Loading
+66 −61
Original line number Diff line number Diff line
@@ -893,13 +893,12 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
 * space, or we've evicted everything and there isn't enough space.
 */
static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
					uint32_t mem_type,
				  const struct ttm_place *place,
				  struct ttm_mem_reg *mem,
				  struct ttm_operation_ctx *ctx)
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
	int ret;

	do {
@@ -908,11 +907,11 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
			return ret;
		if (mem->mm_node)
			break;
		ret = ttm_mem_evict_first(bdev, mem_type, place, ctx);
		ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx);
		if (unlikely(ret != 0))
			return ret;
	} while (1);
	mem->mem_type = mem_type;

	return ttm_bo_add_move_fence(bo, man, mem);
}

@@ -960,6 +959,51 @@ static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
	return true;
}

/**
 * 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
 * @ctx: operation context
 *
 * 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_mem_reg *mem,
				struct ttm_operation_ctx *ctx)
{
	struct ttm_bo_device *bdev = bo->bdev;
	uint32_t mem_type = TTM_PL_SYSTEM;
	struct ttm_mem_type_manager *man;
	uint32_t cur_flags = 0;
	int ret;

	ret = ttm_mem_type_from_place(place, &mem_type);
	if (ret)
		return ret;

	man = &bdev->man[mem_type];
	if (!man->has_type || !man->use_type)
		return -EBUSY;

	if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
		return -EBUSY;

	cur_flags = ttm_bo_select_caching(man, bo->mem.placement, cur_flags);
	/*
	 * Use the access and other non-mapping-related flag bits from
	 * the memory placement flags to the current flags
	 */
	ttm_flag_masked(&cur_flags, place->flags, ~TTM_PL_MASK_MEMTYPE);

	mem->mem_type = mem_type;
	mem->placement = cur_flags;
	return 0;
}

/**
 * Creates space for memory region @mem according to its type.
 *
@@ -974,11 +1018,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
			struct ttm_operation_ctx *ctx)
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_type_manager *man;
	uint32_t mem_type = TTM_PL_SYSTEM;
	uint32_t cur_flags = 0;
	bool type_found = false;
	bool type_ok = false;
	int i, ret;

	ret = reservation_object_reserve_shared(bo->resv, 1);
@@ -988,37 +1028,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
	mem->mm_node = NULL;
	for (i = 0; i < placement->num_placement; ++i) {
		const struct ttm_place *place = &placement->placement[i];
		struct ttm_mem_type_manager *man;

		ret = ttm_mem_type_from_place(place, &mem_type);
		ret = ttm_bo_mem_placement(bo, place, mem, ctx);
		if (ret == -EBUSY)
			continue;
		if (ret)
			return ret;
		man = &bdev->man[mem_type];
		if (!man->has_type || !man->use_type)
			continue;

		type_ok = ttm_bo_mt_compatible(man, mem_type, place,
						&cur_flags);

		if (!type_ok)
			continue;

		type_found = true;
		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
						  cur_flags);
		/*
		 * Use the access and other non-mapping-related flag bits from
		 * the memory placement flags to the current flags
		 */
		ttm_flag_masked(&cur_flags, place->flags,
				~TTM_PL_MASK_MEMTYPE);

		if (mem_type == TTM_PL_SYSTEM) {
			mem->mem_type = mem_type;
			mem->placement = cur_flags;
		mem->mm_node = NULL;
		if (mem->mem_type == TTM_PL_SYSTEM)
			return 0;
		}

		man = &bdev->man[mem->mem_type];
		ret = (*man->func->get_node)(man, bo, place, mem);
		if (unlikely(ret))
			return ret;
@@ -1029,8 +1052,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
				(*man->func->put_node)(man, mem);
				return ret;
			}
			mem->mem_type = mem_type;
			mem->placement = cur_flags;
			return 0;
		}
	}
@@ -1038,37 +1059,21 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
	for (i = 0; i < placement->num_busy_placement; ++i) {
		const struct ttm_place *place = &placement->busy_placement[i];

		ret = ttm_mem_type_from_place(place, &mem_type);
		ret = ttm_bo_mem_placement(bo, place, mem, ctx);
		if (ret == -EBUSY)
			continue;
		if (ret)
			return ret;
		man = &bdev->man[mem_type];
		if (!man->has_type || !man->use_type)
			continue;
		if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
			continue;

		type_found = true;
		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
						  cur_flags);
		/*
		 * Use the access and other non-mapping-related flag bits from
		 * the memory placement flags to the current flags
		 */
		ttm_flag_masked(&cur_flags, place->flags,
				~TTM_PL_MASK_MEMTYPE);

		if (mem_type == TTM_PL_SYSTEM) {
			mem->mem_type = mem_type;
			mem->placement = cur_flags;
		mem->mm_node = NULL;
		if (mem->mem_type == TTM_PL_SYSTEM)
			return 0;
		}

		ret = ttm_bo_mem_force_space(bo, mem_type, place, mem, ctx);
		if (ret == 0 && mem->mm_node) {
			mem->placement = cur_flags;
		ret = ttm_bo_mem_force_space(bo, place, mem, ctx);
		if (ret == 0 && mem->mm_node)
			return 0;
		}

		if (ret && ret != -EBUSY)
			return ret;
	}