Commit 92b2b55e authored by Arunpravin Paneer Selvam's avatar Arunpravin Paneer Selvam Committed by Christian König
Browse files

drm/i915: Implement intersect/compatible functions



Implemented a new intersect and compatible callback function
fetching start offset from drm buddy allocator.

v3: move the bits that are specific to buddy_man (Matthew)
v4: consider the block size /range (Matthew)

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarArunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220820073304.178444-4-Arunpravin.PaneerSelvam@amd.com
parent ded910f3
Loading
Loading
Loading
Loading
+1 −40
Original line number Diff line number Diff line
@@ -361,7 +361,6 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo,
				       const struct ttm_place *place)
{
	struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
	struct ttm_resource *res = bo->resource;

	if (!obj)
		return false;
@@ -378,45 +377,7 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo,
	if (!i915_gem_object_evictable(obj))
		return false;

	switch (res->mem_type) {
	case I915_PL_LMEM0: {
		struct ttm_resource_manager *man =
			ttm_manager_type(bo->bdev, res->mem_type);
		struct i915_ttm_buddy_resource *bman_res =
			to_ttm_buddy_resource(res);
		struct drm_buddy *mm = bman_res->mm;
		struct drm_buddy_block *block;

		if (!place->fpfn && !place->lpfn)
			return true;

		GEM_BUG_ON(!place->lpfn);

		/*
		 * If we just want something mappable then we can quickly check
		 * if the current victim resource is using any of the CPU
		 * visible portion.
		 */
		if (!place->fpfn &&
		    place->lpfn == i915_ttm_buddy_man_visible_size(man))
			return bman_res->used_visible_size > 0;

		/* Real range allocation */
		list_for_each_entry(block, &bman_res->blocks, link) {
			unsigned long fpfn =
				drm_buddy_block_offset(block) >> PAGE_SHIFT;
			unsigned long lpfn = fpfn +
				(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);

			if (place->fpfn < lpfn && place->lpfn > fpfn)
				return true;
		}
		return false;
	} default:
		break;
	}

	return true;
	return ttm_bo_eviction_valuable(bo, place);
}

static void i915_ttm_evict_flags(struct ttm_buffer_object *bo,
+73 −0
Original line number Diff line number Diff line
@@ -173,6 +173,77 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man,
	kfree(bman_res);
}

static bool i915_ttm_buddy_man_intersects(struct ttm_resource_manager *man,
					  struct ttm_resource *res,
					  const struct ttm_place *place,
					  size_t size)
{
	struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
	struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
	struct drm_buddy *mm = &bman->mm;
	struct drm_buddy_block *block;

	if (!place->fpfn && !place->lpfn)
		return true;

	GEM_BUG_ON(!place->lpfn);

	/*
	 * If we just want something mappable then we can quickly check
	 * if the current victim resource is using any of the CPU
	 * visible portion.
	 */
	if (!place->fpfn &&
	    place->lpfn == i915_ttm_buddy_man_visible_size(man))
		return bman_res->used_visible_size > 0;

	/* Check each drm buddy block individually */
	list_for_each_entry(block, &bman_res->blocks, link) {
		unsigned long fpfn =
			drm_buddy_block_offset(block) >> PAGE_SHIFT;
		unsigned long lpfn = fpfn +
			(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);

		if (place->fpfn < lpfn && place->lpfn > fpfn)
			return true;
	}

	return false;
}

static bool i915_ttm_buddy_man_compatible(struct ttm_resource_manager *man,
					  struct ttm_resource *res,
					  const struct ttm_place *place,
					  size_t size)
{
	struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
	struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
	struct drm_buddy *mm = &bman->mm;
	struct drm_buddy_block *block;

	if (!place->fpfn && !place->lpfn)
		return true;

	GEM_BUG_ON(!place->lpfn);

	if (!place->fpfn &&
	    place->lpfn == i915_ttm_buddy_man_visible_size(man))
		return bman_res->used_visible_size == res->num_pages;

	/* Check each drm buddy block individually */
	list_for_each_entry(block, &bman_res->blocks, link) {
		unsigned long fpfn =
			drm_buddy_block_offset(block) >> PAGE_SHIFT;
		unsigned long lpfn = fpfn +
			(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);

		if (fpfn < place->fpfn || lpfn > place->lpfn)
			return false;
	}

	return true;
}

static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man,
				     struct drm_printer *printer)
{
@@ -200,6 +271,8 @@ static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man,
static const struct ttm_resource_manager_func i915_ttm_buddy_manager_func = {
	.alloc = i915_ttm_buddy_man_alloc,
	.free = i915_ttm_buddy_man_free,
	.intersects = i915_ttm_buddy_man_intersects,
	.compatible = i915_ttm_buddy_man_compatible,
	.debug = i915_ttm_buddy_man_debug,
};