Similar to the TTM range manager.

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 51 ++++++++++++--------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index bb01e0fc621c..d59ec07c77bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -23,6 +23,8 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <drm/ttm/ttm_range_manager.h>
+
 #include "amdgpu.h"
 #include "amdgpu_vm.h"
 #include "amdgpu_res_cursor.h"
@@ -367,9 +369,9 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,
        struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
        struct amdgpu_device *adev = to_amdgpu_device(mgr);
        uint64_t vis_usage = 0, mem_bytes, max_bytes;
+       struct ttm_range_mgr_node *node;
        struct drm_mm *mm = &mgr->mm;
        enum drm_mm_insert_mode mode;
-       struct drm_mm_node *nodes;
        unsigned i;
        int r;
 
@@ -384,8 +386,8 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,
        /* bail out quickly if there's likely not enough VRAM for this BO */
        mem_bytes = (u64)mem->num_pages << PAGE_SHIFT;
        if (atomic64_add_return(mem_bytes, &mgr->usage) > max_bytes) {
-               atomic64_sub(mem_bytes, &mgr->usage);
-               return -ENOSPC;
+               r = -ENOSPC;
+               goto error_sub;
        }
 
        if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
@@ -403,13 +405,15 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
                num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
        }
 
-       nodes = kvmalloc_array((uint32_t)num_nodes, sizeof(*nodes),
-                              GFP_KERNEL | __GFP_ZERO);
-       if (!nodes) {
-               atomic64_sub(mem_bytes, &mgr->usage);
-               return -ENOMEM;
+       node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
+                         GFP_KERNEL | __GFP_ZERO);
+       if (!node) {
+               r = -ENOMEM;
+               goto error_sub;
        }
 
+       ttm_resource_init(tbo, place, &node->base);
+
        mode = DRM_MM_INSERT_BEST;
        if (place->flags & TTM_PL_FLAG_TOPDOWN)
                mode = DRM_MM_INSERT_HIGH;
@@ -428,8 +432,9 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,
                if (pages >= pages_per_node)
                        alignment = pages_per_node;
 
-               r = drm_mm_insert_node_in_range(mm, &nodes[i], pages, alignment,
-                                               0, place->fpfn, lpfn, mode);
+               r = drm_mm_insert_node_in_range(mm, &node->mm_nodes[i], pages,
+                                               alignment, 0, place->fpfn,
+                                               lpfn, mode);
                if (unlikely(r)) {
                        if (pages > pages_per_node) {
                                if (is_power_of_2(pages))
@@ -438,11 +443,11 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
                                        pages = rounddown_pow_of_two(pages);
                                continue;
                        }
-                       goto error;
+                       goto error_free;
                }
 
-               vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]);
-               amdgpu_vram_mgr_virt_start(mem, &nodes[i]);
+               vis_usage += amdgpu_vram_mgr_vis_size(adev, &node->mm_nodes[i]);
+               amdgpu_vram_mgr_virt_start(mem, &node->mm_nodes[i]);
                pages_left -= pages;
                ++i;
 
@@ -455,16 +460,17 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
                mem->placement |= TTM_PL_FLAG_CONTIGUOUS;
 
        atomic64_add(vis_usage, &mgr->vis_usage);
-       mem->mm_node = nodes;
+       mem->mm_node = &node->mm_nodes[0];
        return 0;
 
-error:
+error_free:
        while (i--)
-               drm_mm_remove_node(&nodes[i]);
+               drm_mm_remove_node(&node->mm_nodes[i]);
        spin_unlock(&mgr->lock);
-       atomic64_sub(mem->num_pages << PAGE_SHIFT, &mgr->usage);
+       kvfree(node);
 
-       kvfree(nodes);
+error_sub:
+       atomic64_sub(mem_bytes, &mgr->usage);
        return r;
 }
 
@@ -481,13 +487,17 @@ static void amdgpu_vram_mgr_del(struct 
ttm_resource_manager *man,
 {
        struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
        struct amdgpu_device *adev = to_amdgpu_device(mgr);
-       struct drm_mm_node *nodes = mem->mm_node;
+       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];
+
        spin_lock(&mgr->lock);
        while (pages) {
                pages -= nodes->size;
@@ -502,8 +512,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager 
*man,
        atomic64_sub(usage, &mgr->usage);
        atomic64_sub(vis_usage, &mgr->vis_usage);
 
-       kvfree(mem->mm_node);
-       mem->mm_node = NULL;
+       kvfree(node);
 }
 
 /**
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to