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: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220820073304.178444-4-Arunpravin.PaneerSelvam@amd.com
This commit is contained in:
Arunpravin Paneer Selvam 2022-08-20 00:33:02 -07:00 committed by Christian König
parent ded910f368
commit 92b2b55e68
2 changed files with 74 additions and 40 deletions

View File

@ -361,7 +361,6 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place) const struct ttm_place *place)
{ {
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
struct ttm_resource *res = bo->resource;
if (!obj) if (!obj)
return false; return false;
@ -378,45 +377,7 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo,
if (!i915_gem_object_evictable(obj)) if (!i915_gem_object_evictable(obj))
return false; return false;
switch (res->mem_type) { return ttm_bo_eviction_valuable(bo, place);
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;
} }
static void i915_ttm_evict_flags(struct ttm_buffer_object *bo, static void i915_ttm_evict_flags(struct ttm_buffer_object *bo,

View File

@ -173,6 +173,77 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man,
kfree(bman_res); 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, static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man,
struct drm_printer *printer) 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 = { static const struct ttm_resource_manager_func i915_ttm_buddy_manager_func = {
.alloc = i915_ttm_buddy_man_alloc, .alloc = i915_ttm_buddy_man_alloc,
.free = i915_ttm_buddy_man_free, .free = i915_ttm_buddy_man_free,
.intersects = i915_ttm_buddy_man_intersects,
.compatible = i915_ttm_buddy_man_compatible,
.debug = i915_ttm_buddy_man_debug, .debug = i915_ttm_buddy_man_debug,
}; };