* [PATCH 1/4] drm/ttm: add new intersect callback to res mgr
@ 2022-07-20 7:36 Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 2/4] drm/i915: Add intersect callback function Arunpravin Paneer Selvam
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Arunpravin Paneer Selvam @ 2022-07-20 7:36 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, Arunpravin Paneer Selvam, christian.koenig,
matthew.auld
- This allows the resource manager to handle intersection
of placement and resources.
- Add callback function to amdgpu driver module fetching
start offset from buddy allocator.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 19 +++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 33 ++++++++++++++++++++
drivers/gpu/drm/ttm/ttm_range_manager.c | 17 ++++++++++
drivers/gpu/drm/ttm/ttm_resource.c | 28 +++++++++++++++++
include/drm/ttm/ttm_resource.h | 20 ++++++++++++
5 files changed, 117 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 8c6b2284cf56..727c80134aa6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -204,6 +204,24 @@ void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
amdgpu_gart_invalidate_tlb(adev);
}
+/**
+ * amdgpu_gtt_mgr_intersect - test for intersection
+ *
+ * @man: Our manager object
+ * @res: The resource to test
+ * @place: The place for the new allocation
+ * @size: The size of the new allocation
+ *
+ * Simplified intersection test, only interesting if we need GART or not.
+ */
+static bool amdgpu_gtt_mgr_intersect(struct ttm_resource_manager *man,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
+}
+
/**
* amdgpu_gtt_mgr_debug - dump VRAM table
*
@@ -225,6 +243,7 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
.alloc = amdgpu_gtt_mgr_new,
.free = amdgpu_gtt_mgr_del,
+ .intersect = amdgpu_gtt_mgr_intersect,
.debug = amdgpu_gtt_mgr_debug
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 28ec5f8ac1c1..ed0d10fe0b88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -720,6 +720,38 @@ uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr)
return atomic64_read(&mgr->vis_usage);
}
+/**
+ * amdgpu_vram_mgr_intersect - test each drm buddy block for intersection
+ *
+ * @man: TTM memory type manager
+ * @res: The resource to test
+ * @place: The place to test against
+ * @size: Size of the new allocation
+ *
+ * Test each drm buddy block for intersection for eviction decision.
+ */
+static bool amdgpu_vram_mgr_intersect(struct ttm_resource_manager *man,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
+ struct list_head *list = &mgr->blocks;
+ struct drm_buddy_block *block;
+ u32 num_pages = PFN_UP(size);
+ u32 start;
+
+ /* Check each drm buddy block individually */
+ list_for_each_entry(block, list, link) {
+ start = amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT;
+ if (start < place->fpfn ||
+ (place->lpfn && (start + num_pages) > place->lpfn))
+ return false;
+ }
+
+ return true;
+}
+
/**
* amdgpu_vram_mgr_debug - dump VRAM table
*
@@ -753,6 +785,7 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = {
.alloc = amdgpu_vram_mgr_new,
.free = amdgpu_vram_mgr_del,
+ .intersect = amdgpu_vram_mgr_intersect,
.debug = amdgpu_vram_mgr_debug
};
diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c
index d91666721dc6..bf5de1978ead 100644
--- a/drivers/gpu/drm/ttm/ttm_range_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_range_manager.c
@@ -113,6 +113,22 @@ static void ttm_range_man_free(struct ttm_resource_manager *man,
kfree(node);
}
+static bool ttm_range_man_intersect(struct ttm_resource_manager *man,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ struct drm_mm_node *node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
+ u32 num_pages = PFN_UP(size);
+
+ /* Don't evict BOs outside of the requested placement range */
+ if (place->fpfn >= (node->start + num_pages) ||
+ (place->lpfn && place->lpfn <= node->start))
+ return false;
+
+ return true;
+}
+
static void ttm_range_man_debug(struct ttm_resource_manager *man,
struct drm_printer *printer)
{
@@ -126,6 +142,7 @@ static void ttm_range_man_debug(struct ttm_resource_manager *man,
static const struct ttm_resource_manager_func ttm_range_manager_func = {
.alloc = ttm_range_man_alloc,
.free = ttm_range_man_free,
+ .intersect = ttm_range_man_intersect,
.debug = ttm_range_man_debug
};
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 20f9adcc3235..84c21f92b422 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -253,6 +253,34 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
}
EXPORT_SYMBOL(ttm_resource_free);
+/**
+ * ttm_resource_intersect - test for intersection
+ *
+ * @bdev: TTM device structure
+ * @res: The resource to test
+ * @place: The placement to test
+ * @size: How many bytes the new allocation needs.
+ *
+ * Test if @res intersects with @place and @size. Used for testing if evictions
+ * are valueable or not.
+ */
+bool ttm_resource_intersect(struct ttm_device *bdev,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ struct ttm_resource_manager *man;
+
+ if (!res)
+ return false;
+
+ man = ttm_manager_type(bdev, res->mem_type);
+ if (!place || !man->func->intersect)
+ return true;
+
+ return man->func->intersect(man, res, place, size);
+}
+
static bool ttm_resource_places_compat(struct ttm_resource *res,
const struct ttm_place *places,
unsigned num_placement)
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index ca89a48c2460..3f3ab2a8a69e 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -88,6 +88,22 @@ struct ttm_resource_manager_func {
void (*free)(struct ttm_resource_manager *man,
struct ttm_resource *res);
+ /**
+ * struct ttm_resource_manager_func member intersect
+ *
+ * @man: Pointer to a memory type manager.
+ * @res: Pointer to a struct ttm_resource to be checked.
+ * @place: Placement to check against.
+ * @size: Size of the check.
+ *
+ * Test if @res intersects with @place + @size. Used to judge if
+ * evictions are valueable or not.
+ */
+ bool (*intersect)(struct ttm_resource_manager *man,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size);
+
/**
* struct ttm_resource_manager_func member debug
*
@@ -329,6 +345,10 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res);
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
+bool ttm_resource_intersect(struct ttm_device *bdev,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size);
bool ttm_resource_compat(struct ttm_resource *res,
struct ttm_placement *placement);
void ttm_resource_set_bo(struct ttm_resource *res,
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] drm/i915: Add intersect callback function
2022-07-20 7:36 [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Arunpravin Paneer Selvam
@ 2022-07-20 7:36 ` Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 3/4] drm/nouveau: " Arunpravin Paneer Selvam
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Arunpravin Paneer Selvam @ 2022-07-20 7:36 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, Arunpravin Paneer Selvam, christian.koenig,
matthew.auld
Add a new intersect callback function fetching
start offset from backend drm buddy allocator.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
---
drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
index a5109548abc0..30bb8ade67a9 100644
--- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
+++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
@@ -178,6 +178,28 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man,
kfree(bman_res);
}
+static bool i915_ttm_buddy_man_intersect(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 list_head *list = &bman_res->blocks;
+ struct drm_buddy_block *block;
+ u32 num_pages = PFN_UP(size);
+ u32 start;
+
+ /* Check each drm buddy block individually */
+ list_for_each_entry(block, list, link) {
+ start = drm_buddy_block_offset(block) >> PAGE_SHIFT;
+ if (start < place->fpfn ||
+ (place->lpfn && (start + num_pages) > place->lpfn))
+ return false;
+ }
+
+ return true;
+}
+
static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man,
struct drm_printer *printer)
{
@@ -205,6 +227,7 @@ 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,
+ .intersect = i915_ttm_buddy_man_intersect,
.debug = i915_ttm_buddy_man_debug,
};
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] drm/nouveau: Add intersect callback function
2022-07-20 7:36 [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 2/4] drm/i915: Add intersect callback function Arunpravin Paneer Selvam
@ 2022-07-20 7:36 ` Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 4/4] drm/ttm: Switch to using the new intersect callback Arunpravin Paneer Selvam
2022-07-20 8:41 ` [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Christian König
3 siblings, 0 replies; 6+ messages in thread
From: Arunpravin Paneer Selvam @ 2022-07-20 7:36 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, Arunpravin Paneer Selvam, christian.koenig,
matthew.auld
Add a new intersect callback function fetching the
start offset from struct ttm_resource.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
---
drivers/gpu/drm/nouveau/nouveau_mem.c | 15 +++++++++++++++
drivers/gpu/drm/nouveau/nouveau_mem.h | 3 +++
drivers/gpu/drm/nouveau/nouveau_ttm.c | 12 ++++++++++++
3 files changed, 30 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 2e517cdc24c9..b8a773f03c32 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -187,3 +187,18 @@ nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp,
*res = &mem->base;
return 0;
}
+
+bool
+nouveau_mem_intersect(struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ u32 num_pages = PFN_UP(size);
+
+ /* Don't evict BOs outside of the requested placement range */
+ if (place->fpfn >= (res->start + num_pages) ||
+ (place->lpfn && place->lpfn <= res->start))
+ return false;
+
+ return true;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h
index 325551eba5cd..349fefe48e3c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.h
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.h
@@ -25,6 +25,9 @@ int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
struct ttm_resource **);
void nouveau_mem_del(struct ttm_resource_manager *man,
struct ttm_resource *);
+bool nouveau_mem_intersect(struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size);
int nouveau_mem_vram(struct ttm_resource *, bool contig, u8 page);
int nouveau_mem_host(struct ttm_resource *, struct ttm_tt *);
void nouveau_mem_fini(struct nouveau_mem *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 85f1f5a0fe5d..46afd57008dd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -42,6 +42,15 @@ nouveau_manager_del(struct ttm_resource_manager *man,
nouveau_mem_del(man, reg);
}
+static bool
+nouveau_manager_intersect(struct ttm_resource_manager *man,
+ struct ttm_resource *res,
+ const struct ttm_place *place,
+ size_t size)
+{
+ return nouveau_mem_intersect(res, place, size);
+}
+
static int
nouveau_vram_manager_new(struct ttm_resource_manager *man,
struct ttm_buffer_object *bo,
@@ -73,6 +82,7 @@ nouveau_vram_manager_new(struct ttm_resource_manager *man,
const struct ttm_resource_manager_func nouveau_vram_manager = {
.alloc = nouveau_vram_manager_new,
.free = nouveau_manager_del,
+ .intersect = nouveau_manager_intersect,
};
static int
@@ -97,6 +107,7 @@ nouveau_gart_manager_new(struct ttm_resource_manager *man,
const struct ttm_resource_manager_func nouveau_gart_manager = {
.alloc = nouveau_gart_manager_new,
.free = nouveau_manager_del,
+ .intersect = nouveau_manager_intersect,
};
static int
@@ -130,6 +141,7 @@ nv04_gart_manager_new(struct ttm_resource_manager *man,
const struct ttm_resource_manager_func nv04_gart_manager = {
.alloc = nv04_gart_manager_new,
.free = nouveau_manager_del,
+ .intersect = nouveau_manager_intersect,
};
static int
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] drm/ttm: Switch to using the new intersect callback
2022-07-20 7:36 [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 2/4] drm/i915: Add intersect callback function Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 3/4] drm/nouveau: " Arunpravin Paneer Selvam
@ 2022-07-20 7:36 ` Arunpravin Paneer Selvam
2022-07-20 8:44 ` Christian König
2022-07-20 8:41 ` [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Christian König
3 siblings, 1 reply; 6+ messages in thread
From: Arunpravin Paneer Selvam @ 2022-07-20 7:36 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, Arunpravin Paneer Selvam, christian.koenig,
matthew.auld
Use new intersect callback instead of having a generic
placement range verification.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 45 +++++++------------------
drivers/gpu/drm/ttm/ttm_bo.c | 9 +++--
drivers/gpu/drm/ttm/ttm_resource.c | 5 +--
3 files changed, 20 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 170935c294f5..7d25a10395c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1328,11 +1328,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place)
{
- unsigned long num_pages = bo->resource->num_pages;
struct dma_resv_iter resv_cursor;
- struct amdgpu_res_cursor cursor;
struct dma_fence *f;
+ if (!amdgpu_bo_is_amdgpu_bo(bo))
+ return ttm_bo_eviction_valuable(bo, place);
+
/* Swapout? */
if (bo->resource->mem_type == TTM_PL_SYSTEM)
return true;
@@ -1351,40 +1352,20 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
return false;
}
- switch (bo->resource->mem_type) {
- case AMDGPU_PL_PREEMPT:
- /* Preemptible BOs don't own system resources managed by the
- * driver (pages, VRAM, GART space). They point to resources
- * owned by someone else (e.g. pageable memory in user mode
- * or a DMABuf). They are used in a preemptible context so we
- * can guarantee no deadlocks and good QoS in case of MMU
- * notifiers or DMABuf move notifiers from the resource owner.
- */
+ /* Preemptible BOs don't own system resources managed by the
+ * driver (pages, VRAM, GART space). They point to resources
+ * owned by someone else (e.g. pageable memory in user mode
+ * or a DMABuf). They are used in a preemptible context so we
+ * can guarantee no deadlocks and good QoS in case of MMU
+ * notifiers or DMABuf move notifiers from the resource owner.
+ */
+ if (bo->resource->mem_type == AMDGPU_PL_PREEMPT)
return false;
- case TTM_PL_TT:
- if (amdgpu_bo_is_amdgpu_bo(bo) &&
- amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
- return false;
- return true;
- case TTM_PL_VRAM:
- /* Check each drm MM node individually */
- amdgpu_res_first(bo->resource, 0, (u64)num_pages << PAGE_SHIFT,
- &cursor);
- while (cursor.remaining) {
- if (place->fpfn < PFN_DOWN(cursor.start + cursor.size)
- && !(place->lpfn &&
- place->lpfn <= PFN_DOWN(cursor.start)))
- return true;
-
- amdgpu_res_next(&cursor, cursor.size);
- }
+ if (bo->resource->mem_type == TTM_PL_TT &&
+ amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
return false;
- default:
- break;
- }
-
return ttm_bo_eviction_valuable(bo, place);
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index c1bd006a5525..03409409e43e 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -518,6 +518,9 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo,
bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place)
{
+ struct ttm_resource *res = bo->resource;
+ struct ttm_device *bdev = bo->bdev;
+
dma_resv_assert_held(bo->base.resv);
if (bo->resource->mem_type == TTM_PL_SYSTEM)
return true;
@@ -525,11 +528,7 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
/* Don't evict this BO if it's outside of the
* requested placement range
*/
- if (place->fpfn >= (bo->resource->start + bo->resource->num_pages) ||
- (place->lpfn && place->lpfn <= bo->resource->start))
- return false;
-
- return true;
+ return ttm_resource_intersect(bdev, res, place, bo->base.size);
}
EXPORT_SYMBOL(ttm_bo_eviction_valuable);
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 84c21f92b422..ff3e9058943c 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -285,6 +285,8 @@ static bool ttm_resource_places_compat(struct ttm_resource *res,
const struct ttm_place *places,
unsigned num_placement)
{
+ struct ttm_buffer_object *bo = res->bo;
+ struct ttm_device *bdev = bo->bdev;
unsigned i;
if (res->placement & TTM_PL_FLAG_TEMPORARY)
@@ -293,8 +295,7 @@ static bool ttm_resource_places_compat(struct ttm_resource *res,
for (i = 0; i < num_placement; i++) {
const struct ttm_place *heap = &places[i];
- if (res->start < heap->fpfn || (heap->lpfn &&
- (res->start + res->num_pages) > heap->lpfn))
+ if (!ttm_resource_intersect(bdev, res, heap, bo->base.size))
continue;
if ((res->mem_type == heap->mem_type) &&
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/4] drm/ttm: add new intersect callback to res mgr
2022-07-20 7:36 [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Arunpravin Paneer Selvam
` (2 preceding siblings ...)
2022-07-20 7:36 ` [PATCH 4/4] drm/ttm: Switch to using the new intersect callback Arunpravin Paneer Selvam
@ 2022-07-20 8:41 ` Christian König
3 siblings, 0 replies; 6+ messages in thread
From: Christian König @ 2022-07-20 8:41 UTC (permalink / raw)
To: Arunpravin Paneer Selvam, dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, matthew.auld
Am 20.07.22 um 09:36 schrieb Arunpravin Paneer Selvam:
> - This allows the resource manager to handle intersection
> of placement and resources.
>
> - Add callback function to amdgpu driver module fetching
> start offset from buddy allocator.
Probably better to only add the callback and ttm_resource_intersect()
wrapper function in this patch and then move the amdgpu and
ttm_range_manager changes to separate patches.
Apart from that looks good to me.
Regards,
Christian.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 19 +++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 33 ++++++++++++++++++++
> drivers/gpu/drm/ttm/ttm_range_manager.c | 17 ++++++++++
> drivers/gpu/drm/ttm/ttm_resource.c | 28 +++++++++++++++++
> include/drm/ttm/ttm_resource.h | 20 ++++++++++++
> 5 files changed, 117 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> index 8c6b2284cf56..727c80134aa6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> @@ -204,6 +204,24 @@ void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
> amdgpu_gart_invalidate_tlb(adev);
> }
>
> +/**
> + * amdgpu_gtt_mgr_intersect - test for intersection
> + *
> + * @man: Our manager object
> + * @res: The resource to test
> + * @place: The place for the new allocation
> + * @size: The size of the new allocation
> + *
> + * Simplified intersection test, only interesting if we need GART or not.
> + */
> +static bool amdgpu_gtt_mgr_intersect(struct ttm_resource_manager *man,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size)
> +{
> + return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
> +}
> +
> /**
> * amdgpu_gtt_mgr_debug - dump VRAM table
> *
> @@ -225,6 +243,7 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
> static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
> .alloc = amdgpu_gtt_mgr_new,
> .free = amdgpu_gtt_mgr_del,
> + .intersect = amdgpu_gtt_mgr_intersect,
> .debug = amdgpu_gtt_mgr_debug
> };
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> index 28ec5f8ac1c1..ed0d10fe0b88 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> @@ -720,6 +720,38 @@ uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr)
> return atomic64_read(&mgr->vis_usage);
> }
>
> +/**
> + * amdgpu_vram_mgr_intersect - test each drm buddy block for intersection
> + *
> + * @man: TTM memory type manager
> + * @res: The resource to test
> + * @place: The place to test against
> + * @size: Size of the new allocation
> + *
> + * Test each drm buddy block for intersection for eviction decision.
> + */
> +static bool amdgpu_vram_mgr_intersect(struct ttm_resource_manager *man,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size)
> +{
> + struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
> + struct list_head *list = &mgr->blocks;
> + struct drm_buddy_block *block;
> + u32 num_pages = PFN_UP(size);
> + u32 start;
> +
> + /* Check each drm buddy block individually */
> + list_for_each_entry(block, list, link) {
> + start = amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT;
> + if (start < place->fpfn ||
> + (place->lpfn && (start + num_pages) > place->lpfn))
> + return false;
> + }
> +
> + return true;
> +}
> +
> /**
> * amdgpu_vram_mgr_debug - dump VRAM table
> *
> @@ -753,6 +785,7 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
> static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = {
> .alloc = amdgpu_vram_mgr_new,
> .free = amdgpu_vram_mgr_del,
> + .intersect = amdgpu_vram_mgr_intersect,
> .debug = amdgpu_vram_mgr_debug
> };
>
> diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c
> index d91666721dc6..bf5de1978ead 100644
> --- a/drivers/gpu/drm/ttm/ttm_range_manager.c
> +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c
> @@ -113,6 +113,22 @@ static void ttm_range_man_free(struct ttm_resource_manager *man,
> kfree(node);
> }
>
> +static bool ttm_range_man_intersect(struct ttm_resource_manager *man,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size)
> +{
> + struct drm_mm_node *node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
> + u32 num_pages = PFN_UP(size);
> +
> + /* Don't evict BOs outside of the requested placement range */
> + if (place->fpfn >= (node->start + num_pages) ||
> + (place->lpfn && place->lpfn <= node->start))
> + return false;
> +
> + return true;
> +}
> +
> static void ttm_range_man_debug(struct ttm_resource_manager *man,
> struct drm_printer *printer)
> {
> @@ -126,6 +142,7 @@ static void ttm_range_man_debug(struct ttm_resource_manager *man,
> static const struct ttm_resource_manager_func ttm_range_manager_func = {
> .alloc = ttm_range_man_alloc,
> .free = ttm_range_man_free,
> + .intersect = ttm_range_man_intersect,
> .debug = ttm_range_man_debug
> };
>
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index 20f9adcc3235..84c21f92b422 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -253,6 +253,34 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
> }
> EXPORT_SYMBOL(ttm_resource_free);
>
> +/**
> + * ttm_resource_intersect - test for intersection
> + *
> + * @bdev: TTM device structure
> + * @res: The resource to test
> + * @place: The placement to test
> + * @size: How many bytes the new allocation needs.
> + *
> + * Test if @res intersects with @place and @size. Used for testing if evictions
> + * are valueable or not.
> + */
> +bool ttm_resource_intersect(struct ttm_device *bdev,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size)
> +{
> + struct ttm_resource_manager *man;
> +
> + if (!res)
> + return false;
> +
> + man = ttm_manager_type(bdev, res->mem_type);
> + if (!place || !man->func->intersect)
> + return true;
> +
> + return man->func->intersect(man, res, place, size);
> +}
> +
> static bool ttm_resource_places_compat(struct ttm_resource *res,
> const struct ttm_place *places,
> unsigned num_placement)
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index ca89a48c2460..3f3ab2a8a69e 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -88,6 +88,22 @@ struct ttm_resource_manager_func {
> void (*free)(struct ttm_resource_manager *man,
> struct ttm_resource *res);
>
> + /**
> + * struct ttm_resource_manager_func member intersect
> + *
> + * @man: Pointer to a memory type manager.
> + * @res: Pointer to a struct ttm_resource to be checked.
> + * @place: Placement to check against.
> + * @size: Size of the check.
> + *
> + * Test if @res intersects with @place + @size. Used to judge if
> + * evictions are valueable or not.
> + */
> + bool (*intersect)(struct ttm_resource_manager *man,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size);
> +
> /**
> * struct ttm_resource_manager_func member debug
> *
> @@ -329,6 +345,10 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
> const struct ttm_place *place,
> struct ttm_resource **res);
> void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
> +bool ttm_resource_intersect(struct ttm_device *bdev,
> + struct ttm_resource *res,
> + const struct ttm_place *place,
> + size_t size);
> bool ttm_resource_compat(struct ttm_resource *res,
> struct ttm_placement *placement);
> void ttm_resource_set_bo(struct ttm_resource *res,
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 4/4] drm/ttm: Switch to using the new intersect callback
2022-07-20 7:36 ` [PATCH 4/4] drm/ttm: Switch to using the new intersect callback Arunpravin Paneer Selvam
@ 2022-07-20 8:44 ` Christian König
0 siblings, 0 replies; 6+ messages in thread
From: Christian König @ 2022-07-20 8:44 UTC (permalink / raw)
To: Arunpravin Paneer Selvam, dri-devel, amd-gfx, intel-gfx, nouveau
Cc: alexander.deucher, matthew.auld
Am 20.07.22 um 09:36 schrieb Arunpravin Paneer Selvam:
> Use new intersect callback instead of having a generic
> placement range verification.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 45 +++++++------------------
> drivers/gpu/drm/ttm/ttm_bo.c | 9 +++--
> drivers/gpu/drm/ttm/ttm_resource.c | 5 +--
> 3 files changed, 20 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 170935c294f5..7d25a10395c0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1328,11 +1328,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
> static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
> const struct ttm_place *place)
> {
> - unsigned long num_pages = bo->resource->num_pages;
> struct dma_resv_iter resv_cursor;
> - struct amdgpu_res_cursor cursor;
> struct dma_fence *f;
>
> + if (!amdgpu_bo_is_amdgpu_bo(bo))
> + return ttm_bo_eviction_valuable(bo, place);
> +
> /* Swapout? */
> if (bo->resource->mem_type == TTM_PL_SYSTEM)
> return true;
> @@ -1351,40 +1352,20 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
> return false;
> }
>
> - switch (bo->resource->mem_type) {
> - case AMDGPU_PL_PREEMPT:
> - /* Preemptible BOs don't own system resources managed by the
> - * driver (pages, VRAM, GART space). They point to resources
> - * owned by someone else (e.g. pageable memory in user mode
> - * or a DMABuf). They are used in a preemptible context so we
> - * can guarantee no deadlocks and good QoS in case of MMU
> - * notifiers or DMABuf move notifiers from the resource owner.
> - */
> + /* Preemptible BOs don't own system resources managed by the
> + * driver (pages, VRAM, GART space). They point to resources
> + * owned by someone else (e.g. pageable memory in user mode
> + * or a DMABuf). They are used in a preemptible context so we
> + * can guarantee no deadlocks and good QoS in case of MMU
> + * notifiers or DMABuf move notifiers from the resource owner.
> + */
> + if (bo->resource->mem_type == AMDGPU_PL_PREEMPT)
> return false;
> - case TTM_PL_TT:
> - if (amdgpu_bo_is_amdgpu_bo(bo) &&
> - amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
> - return false;
> - return true;
>
> - case TTM_PL_VRAM:
> - /* Check each drm MM node individually */
> - amdgpu_res_first(bo->resource, 0, (u64)num_pages << PAGE_SHIFT,
> - &cursor);
> - while (cursor.remaining) {
> - if (place->fpfn < PFN_DOWN(cursor.start + cursor.size)
> - && !(place->lpfn &&
> - place->lpfn <= PFN_DOWN(cursor.start)))
> - return true;
> -
> - amdgpu_res_next(&cursor, cursor.size);
> - }
> + if (bo->resource->mem_type == TTM_PL_TT &&
> + amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
> return false;
>
> - default:
> - break;
> - }
> -
> return ttm_bo_eviction_valuable(bo, place);
> }
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index c1bd006a5525..03409409e43e 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -518,6 +518,9 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo,
> bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
> const struct ttm_place *place)
> {
> + struct ttm_resource *res = bo->resource;
> + struct ttm_device *bdev = bo->bdev;
> +
> dma_resv_assert_held(bo->base.resv);
> if (bo->resource->mem_type == TTM_PL_SYSTEM)
> return true;
> @@ -525,11 +528,7 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
> /* Don't evict this BO if it's outside of the
> * requested placement range
> */
> - if (place->fpfn >= (bo->resource->start + bo->resource->num_pages) ||
> - (place->lpfn && place->lpfn <= bo->resource->start))
> - return false;
> -
> - return true;
> + return ttm_resource_intersect(bdev, res, place, bo->base.size);
> }
> EXPORT_SYMBOL(ttm_bo_eviction_valuable);
>
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
> index 84c21f92b422..ff3e9058943c 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -285,6 +285,8 @@ static bool ttm_resource_places_compat(struct ttm_resource *res,
> const struct ttm_place *places,
> unsigned num_placement)
> {
> + struct ttm_buffer_object *bo = res->bo;
> + struct ttm_device *bdev = bo->bdev;
> unsigned i;
>
> if (res->placement & TTM_PL_FLAG_TEMPORARY)
> @@ -293,8 +295,7 @@ static bool ttm_resource_places_compat(struct ttm_resource *res,
> for (i = 0; i < num_placement; i++) {
> const struct ttm_place *heap = &places[i];
>
> - if (res->start < heap->fpfn || (heap->lpfn &&
> - (res->start + res->num_pages) > heap->lpfn))
> + if (!ttm_resource_intersect(bdev, res, heap, bo->base.size))
Thinking more about it that probably won't work like this.
Intersection doesn't mean the placement is compatible (e.g. it can be
that we only partial intersect).
We need to add a separate callback for that I think.
Regards,
Christian.
> continue;
>
> if ((res->mem_type == heap->mem_type) &&
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-07-20 8:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-20 7:36 [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 2/4] drm/i915: Add intersect callback function Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 3/4] drm/nouveau: " Arunpravin Paneer Selvam
2022-07-20 7:36 ` [PATCH 4/4] drm/ttm: Switch to using the new intersect callback Arunpravin Paneer Selvam
2022-07-20 8:44 ` Christian König
2022-07-20 8:41 ` [PATCH 1/4] drm/ttm: add new intersect callback to res mgr Christian König
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox