[PATCH 13/13] drm/ttm: flip the switch for driver allocated resources
Matthew Auld
matthew.william.auld at gmail.com
Wed May 5 16:44:08 UTC 2021
On Fri, 30 Apr 2021 at 10:25, Christian König
<ckoenig.leichtzumerken at gmail.com> wrote:
>
> Instead of both driver and TTM allocating memory finalize embedding the
> ttm_resource object as base into the driver backends.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 44 ++++++--------
> drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +-
> .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h | 5 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 60 +++++++++----------
> drivers/gpu/drm/drm_gem_vram_helper.c | 3 +-
> drivers/gpu/drm/nouveau/nouveau_bo.c | 8 +--
> drivers/gpu/drm/nouveau/nouveau_mem.c | 11 ++--
> drivers/gpu/drm/nouveau/nouveau_mem.h | 14 ++---
> drivers/gpu/drm/nouveau/nouveau_ttm.c | 32 +++++-----
> drivers/gpu/drm/ttm/ttm_range_manager.c | 23 +++----
> drivers/gpu/drm/ttm/ttm_resource.c | 15 +----
> drivers/gpu/drm/ttm/ttm_sys_manager.c | 12 ++--
> drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 24 ++++----
> drivers/gpu/drm/vmwgfx/vmwgfx_thp.c | 27 ++++-----
> include/drm/ttm/ttm_range_manager.h | 3 +-
> include/drm/ttm/ttm_resource.h | 43 ++++++-------
> 16 files changed, 140 insertions(+), 186 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> index 2e7dffd3614d..d6c1960abf64 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> @@ -40,8 +40,7 @@ to_gtt_mgr(struct ttm_resource_manager *man)
> static inline struct amdgpu_gtt_node *
> to_amdgpu_gtt_node(struct ttm_resource *res)
> {
> - return container_of(res->mm_node, struct amdgpu_gtt_node,
> - base.mm_nodes[0]);
> + return container_of(res, struct amdgpu_gtt_node, base.base);
> }
>
> /**
> @@ -92,13 +91,13 @@ static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,
> /**
> * amdgpu_gtt_mgr_has_gart_addr - Check if mem has address space
> *
> - * @mem: the mem object to check
> + * @res: the mem object to check
> *
> * Check if a mem object has already address space allocated.
> */
> -bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem)
> +bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *res)
> {
> - struct amdgpu_gtt_node *node = to_amdgpu_gtt_node(mem);
> + struct amdgpu_gtt_node *node = to_amdgpu_gtt_node(res);
>
> return drm_mm_node_allocated(&node->base.mm_nodes[0]);
> }
> @@ -116,19 +115,20 @@ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem)
> static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
> struct ttm_buffer_object *tbo,
> const struct ttm_place *place,
> - struct ttm_resource *mem)
> + struct ttm_resource **res)
> {
> struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
> + uint32_t num_pages = PFN_UP(tbo->base.size);
> struct amdgpu_gtt_node *node;
> int r;
>
> spin_lock(&mgr->lock);
> - if ((tbo->resource == mem || tbo->resource->mem_type != TTM_PL_TT) &&
> - atomic64_read(&mgr->available) < mem->num_pages) {
> + if (tbo->resource && tbo->resource->mem_type != TTM_PL_TT &&
> + atomic64_read(&mgr->available) < num_pages) {
> spin_unlock(&mgr->lock);
> return -ENOSPC;
> }
> - atomic64_sub(mem->num_pages, &mgr->available);
> + atomic64_sub(num_pages, &mgr->available);
> spin_unlock(&mgr->lock);
>
> node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL);
> @@ -144,29 +144,28 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
> spin_lock(&mgr->lock);
> r = drm_mm_insert_node_in_range(&mgr->mm,
> &node->base.mm_nodes[0],
> - mem->num_pages,
> - tbo->page_alignment, 0,
> - place->fpfn, place->lpfn,
> + num_pages, tbo->page_alignment,
> + 0, place->fpfn, place->lpfn,
> DRM_MM_INSERT_BEST);
> spin_unlock(&mgr->lock);
> if (unlikely(r))
> goto err_free;
>
> - mem->start = node->base.mm_nodes[0].start;
> + node->base.base.start = node->base.mm_nodes[0].start;
> } else {
> node->base.mm_nodes[0].start = 0;
> - node->base.mm_nodes[0].size = mem->num_pages;
> - mem->start = AMDGPU_BO_INVALID_OFFSET;
> + node->base.mm_nodes[0].size = node->base.base.num_pages;
> + node->base.base.start = AMDGPU_BO_INVALID_OFFSET;
> }
>
> - mem->mm_node = &node->base.mm_nodes[0];
> + *res = &node->base.base;
> return 0;
>
> err_free:
> kfree(node);
>
> err_out:
> - atomic64_add(mem->num_pages, &mgr->available);
> + atomic64_add(num_pages, &mgr->available);
>
> return r;
> }
> @@ -180,21 +179,16 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
> * Free the allocated GTT again.
> */
> static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
> - struct ttm_resource *mem)
> + struct ttm_resource *res)
> {
> + struct amdgpu_gtt_node *node = to_amdgpu_gtt_node(res);
> struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
> - struct amdgpu_gtt_node *node;
> -
> - if (!mem->mm_node)
> - return;
> -
> - node = to_amdgpu_gtt_node(mem);
>
> spin_lock(&mgr->lock);
> if (drm_mm_node_allocated(&node->base.mm_nodes[0]))
> drm_mm_remove_node(&node->base.mm_nodes[0]);
> spin_unlock(&mgr->lock);
> - atomic64_add(mem->num_pages, &mgr->available);
> + atomic64_add(res->num_pages, &mgr->available);
>
> kfree(node);
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index e669a3adac44..84142eed66df 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -1315,7 +1315,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
> if (bo->base.resv == &bo->base._resv)
> amdgpu_amdkfd_remove_fence_on_pt_pd_bos(abo);
>
> - if (bo->resource->mem_type != TTM_PL_VRAM || !bo->resource->mm_node ||
> + if (bo->resource->mem_type != TTM_PL_VRAM ||
> !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE))
> return;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> index 40f2adf305bc..59e0fefb15aa 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> @@ -28,6 +28,7 @@
>
> #include <drm/drm_mm.h>
> #include <drm/ttm/ttm_resource.h>
> +#include <drm/ttm/ttm_range_manager.h>
>
> /* state back for walking over vram_mgr and gtt_mgr allocations */
> struct amdgpu_res_cursor {
> @@ -53,7 +54,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
> {
> struct drm_mm_node *node;
>
> - if (!res || !res->mm_node) {
> + if (!res) {
> cur->start = start;
> cur->size = size;
> cur->remaining = size;
> @@ -63,7 +64,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>
> BUG_ON(start + size > res->num_pages << PAGE_SHIFT);
>
> - node = res->mm_node;
> + node = to_ttm_range_mgr_node(res)->mm_nodes;
> while (start >= node->size << PAGE_SHIFT)
> start -= node++->size << PAGE_SHIFT;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> index d59ec07c77bb..c8feae788e79 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> @@ -215,19 +215,20 @@ static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev,
> u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo)
> {
> struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
> - struct ttm_resource *mem = bo->tbo.resource;
> - struct drm_mm_node *nodes = mem->mm_node;
> - unsigned pages = mem->num_pages;
> + struct ttm_resource *res = bo->tbo.resource;
> + unsigned pages = res->num_pages;
> + struct drm_mm_node *mm;
> u64 usage;
>
> if (amdgpu_gmc_vram_full_visible(&adev->gmc))
> return amdgpu_bo_size(bo);
>
> - if (mem->start >= adev->gmc.visible_vram_size >> PAGE_SHIFT)
> + if (res->start >= adev->gmc.visible_vram_size >> PAGE_SHIFT)
> return 0;
>
> - for (usage = 0; nodes && pages; pages -= nodes->size, nodes++)
> - usage += amdgpu_vram_mgr_vis_size(adev, nodes);
> + mm = &container_of(res, struct ttm_range_mgr_node, base)->mm_nodes[0];
> + for (usage = 0; pages; pages -= mm->size, mm++)
> + usage += amdgpu_vram_mgr_vis_size(adev, mm);
>
> return usage;
> }
> @@ -363,7 +364,7 @@ static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
> static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> struct ttm_buffer_object *tbo,
> const struct ttm_place *place,
> - struct ttm_resource *mem)
> + struct ttm_resource **res)
> {
> unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
> struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
> @@ -384,7 +385,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> max_bytes -= AMDGPU_VM_RESERVED_VRAM;
>
> /* bail out quickly if there's likely not enough VRAM for this BO */
> - mem_bytes = (u64)mem->num_pages << PAGE_SHIFT;
> + mem_bytes = tbo->base.size;
> if (atomic64_add_return(mem_bytes, &mgr->usage) > max_bytes) {
> r = -ENOSPC;
> goto error_sub;
> @@ -402,7 +403,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> #endif
> pages_per_node = max_t(uint32_t, pages_per_node,
> tbo->page_alignment);
> - num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
> + num_nodes = DIV_ROUND_UP(PFN_UP(mem_bytes), pages_per_node);
> }
>
> node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
> @@ -418,8 +419,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> if (place->flags & TTM_PL_FLAG_TOPDOWN)
> mode = DRM_MM_INSERT_HIGH;
>
> - mem->start = 0;
> - pages_left = mem->num_pages;
> + pages_left = node->base.num_pages;
>
> /* Limit maximum size to 2GB due to SG table limitations */
> pages = min(pages_left, 2UL << (30 - PAGE_SHIFT));
> @@ -447,7 +447,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> }
>
> vis_usage += amdgpu_vram_mgr_vis_size(adev, &node->mm_nodes[i]);
> - amdgpu_vram_mgr_virt_start(mem, &node->mm_nodes[i]);
> + amdgpu_vram_mgr_virt_start(&node->base, &node->mm_nodes[i]);
> pages_left -= pages;
> ++i;
>
> @@ -457,10 +457,10 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> spin_unlock(&mgr->lock);
>
> if (i == 1)
> - mem->placement |= TTM_PL_FLAG_CONTIGUOUS;
> + node->base.placement |= TTM_PL_FLAG_CONTIGUOUS;
>
> atomic64_add(vis_usage, &mgr->vis_usage);
> - mem->mm_node = &node->mm_nodes[0];
> + *res = &node->base;
> return 0;
>
> error_free:
> @@ -483,28 +483,22 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
> * Free the allocated VRAM again.
> */
> static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
> - struct ttm_resource *mem)
> + struct ttm_resource *res)
> {
> + struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res);
> struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
> struct amdgpu_device *adev = to_amdgpu_device(mgr);
> - struct ttm_range_mgr_node *node;
> uint64_t usage = 0, vis_usage = 0;
> - unsigned pages = mem->num_pages;
> - struct drm_mm_node *nodes;
> -
> - if (!mem->mm_node)
> - return;
> -
> - node = to_ttm_range_mgr_node(mem);
> - nodes = &node->mm_nodes[0];
> + unsigned i, pages = res->num_pages;
>
> spin_lock(&mgr->lock);
> - while (pages) {
> - pages -= nodes->size;
> - drm_mm_remove_node(nodes);
> - usage += nodes->size << PAGE_SHIFT;
> - vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes);
> - ++nodes;
> + for (i = 0, pages = res->num_pages; pages;
No need to initialise pages twice I suppose.
With the issue Nirmoy spotted fixed,
Reviewed-by: Matthew Auld <matthew.auld at intel.com>
More information about the dri-devel
mailing list