Re: [PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-02-10 Thread Matthew Auld

On 08/02/2022 11:20, Arunpravin wrote:



On 04/02/22 6:53 pm, Christian König wrote:

Am 04.02.22 um 12:22 schrieb Arunpravin:

On 28/01/22 7:48 pm, Matthew Auld wrote:

On Thu, 27 Jan 2022 at 14:11, Arunpravin
 wrote:

- Remove drm_mm references and replace with drm buddy functionalities
- Add res cursor support for drm buddy

v2(Matthew Auld):
- replace spinlock with mutex as we call kmem_cache_zalloc
  (..., GFP_KERNEL) in drm_buddy_alloc() function

- lock drm_buddy_block_trim() function as it calls
  mark_free/mark_split are all globally visible

v3(Matthew Auld):
- remove trim method error handling as we address the failure case
  at drm_buddy_block_trim() function

v4:
- fix warnings reported by kernel test robot 

v5:
- fix merge conflict issue

v6:
- fix warnings reported by kernel test robot 

Signed-off-by: Arunpravin 
---
   drivers/gpu/drm/Kconfig   |   1 +
   .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
   4 files changed, 231 insertions(+), 133 deletions(-)




-/**
- * amdgpu_vram_mgr_virt_start - update virtual start address
- *
- * @mem: ttm_resource to update
- * @node: just allocated node
- *
- * Calculate a virtual BO start address to easily check if everything is CPU
- * accessible.
- */
-static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
-  struct drm_mm_node *node)
-{
-   unsigned long start;
-
-   start = node->start + node->size;
-   if (start > mem->num_pages)
-   start -= mem->num_pages;
-   else
-   start = 0;
-   mem->start = max(mem->start, start);
-}
-
   /**
* amdgpu_vram_mgr_new - allocate new ranges
*
@@ -366,13 +357,13 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
 const struct ttm_place *place,
 struct ttm_resource **res)
   {
-   unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
+   unsigned long lpfn, pages_per_node, pages_left, pages, n_pages;
+   u64 vis_usage = 0, mem_bytes, max_bytes, min_page_size;
  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 = >mm;
-   enum drm_mm_insert_mode mode;
+   struct amdgpu_vram_mgr_node *node;
+   struct drm_buddy *mm = >mm;
+   struct drm_buddy_block *block;
  unsigned i;
  int r;

@@ -391,10 +382,9 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,
  goto error_sub;
  }

-   if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
+   if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
  pages_per_node = ~0ul;
-   num_nodes = 1;
-   } else {
+   else {
   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  pages_per_node = HPAGE_PMD_NR;
   #else
@@ -403,11 +393,9 @@ 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_ULL(PFN_UP(mem_bytes), pages_per_node);
  }

-   node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
-   GFP_KERNEL | __GFP_ZERO);
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
  if (!node) {
  r = -ENOMEM;
  goto error_sub;
@@ -415,9 +403,17 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,

  ttm_resource_init(tbo, place, >base);

-   mode = DRM_MM_INSERT_BEST;
+   INIT_LIST_HEAD(>blocks);
+
  if (place->flags & TTM_PL_FLAG_TOPDOWN)
-   mode = DRM_MM_INSERT_HIGH;
+   node->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
+
+   if (place->fpfn || lpfn != man->size)
+   /* Allocate blocks in desired range */
+   node->flags |= DRM_BUDDY_RANGE_ALLOCATION;
+
+   min_page_size = mgr->default_page_size;
+   BUG_ON(min_page_size < mm->chunk_size);

  pages_left = node->base.num_pages;

@@ -425,36 +421,61 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
  pages = min(pages_left, 2UL << (30 - PAGE_SHIFT));

  i = 0;
-   spin_lock(>lock);
  while (pages_left) {
-   uint32_t alignment = tbo->page_alignment;
-
  if (pages >= pages_per_node)
-   alignment = pages_per_node;
-
-   r = drm_mm_insert_node_in_range(mm, >mm_nodes[i], pages,
-   alignment, 0, place->fpfn,
- 

Re: [PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-02-08 Thread Arunpravin



On 04/02/22 6:53 pm, Christian König wrote:
> Am 04.02.22 um 12:22 schrieb Arunpravin:
>> On 28/01/22 7:48 pm, Matthew Auld wrote:
>>> On Thu, 27 Jan 2022 at 14:11, Arunpravin
>>>  wrote:
 - Remove drm_mm references and replace with drm buddy functionalities
 - Add res cursor support for drm buddy

 v2(Matthew Auld):
- replace spinlock with mutex as we call kmem_cache_zalloc
  (..., GFP_KERNEL) in drm_buddy_alloc() function

- lock drm_buddy_block_trim() function as it calls
  mark_free/mark_split are all globally visible

 v3(Matthew Auld):
- remove trim method error handling as we address the failure case
  at drm_buddy_block_trim() function

 v4:
- fix warnings reported by kernel test robot 

 v5:
- fix merge conflict issue

 v6:
- fix warnings reported by kernel test robot 

 Signed-off-by: Arunpravin 
 ---
   drivers/gpu/drm/Kconfig   |   1 +
   .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
   4 files changed, 231 insertions(+), 133 deletions(-)
>>> 
>>>
 -/**
 - * amdgpu_vram_mgr_virt_start - update virtual start address
 - *
 - * @mem: ttm_resource to update
 - * @node: just allocated node
 - *
 - * Calculate a virtual BO start address to easily check if everything is 
 CPU
 - * accessible.
 - */
 -static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
 -  struct drm_mm_node *node)
 -{
 -   unsigned long start;
 -
 -   start = node->start + node->size;
 -   if (start > mem->num_pages)
 -   start -= mem->num_pages;
 -   else
 -   start = 0;
 -   mem->start = max(mem->start, start);
 -}
 -
   /**
* amdgpu_vram_mgr_new - allocate new ranges
*
 @@ -366,13 +357,13 @@ static int amdgpu_vram_mgr_new(struct 
 ttm_resource_manager *man,
 const struct ttm_place *place,
 struct ttm_resource **res)
   {
 -   unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
 +   unsigned long lpfn, pages_per_node, pages_left, pages, n_pages;
 +   u64 vis_usage = 0, mem_bytes, max_bytes, min_page_size;
  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 = >mm;
 -   enum drm_mm_insert_mode mode;
 +   struct amdgpu_vram_mgr_node *node;
 +   struct drm_buddy *mm = >mm;
 +   struct drm_buddy_block *block;
  unsigned i;
  int r;

 @@ -391,10 +382,9 @@ static int amdgpu_vram_mgr_new(struct 
 ttm_resource_manager *man,
  goto error_sub;
  }

 -   if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
 +   if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
  pages_per_node = ~0ul;
 -   num_nodes = 1;
 -   } else {
 +   else {
   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  pages_per_node = HPAGE_PMD_NR;
   #else
 @@ -403,11 +393,9 @@ 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_ULL(PFN_UP(mem_bytes), 
 pages_per_node);
  }

 -   node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
 -   GFP_KERNEL | __GFP_ZERO);
 +   node = kzalloc(sizeof(*node), GFP_KERNEL);
  if (!node) {
  r = -ENOMEM;
  goto error_sub;
 @@ -415,9 +403,17 @@ static int amdgpu_vram_mgr_new(struct 
 ttm_resource_manager *man,

  ttm_resource_init(tbo, place, >base);

 -   mode = DRM_MM_INSERT_BEST;
 +   INIT_LIST_HEAD(>blocks);
 +
  if (place->flags & TTM_PL_FLAG_TOPDOWN)
 -   mode = DRM_MM_INSERT_HIGH;
 +   node->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
 +
 +   if (place->fpfn || lpfn != man->size)
 +   /* Allocate blocks in desired range */
 +   node->flags |= DRM_BUDDY_RANGE_ALLOCATION;
 +
 +   min_page_size = mgr->default_page_size;
 +   BUG_ON(min_page_size < mm->chunk_size);

  pages_left = node->base.num_pages;

 @@ -425,36 +421,61 @@ 

Re: [PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-02-04 Thread Christian König

Am 04.02.22 um 12:22 schrieb Arunpravin:

On 28/01/22 7:48 pm, Matthew Auld wrote:

On Thu, 27 Jan 2022 at 14:11, Arunpravin
 wrote:

- Remove drm_mm references and replace with drm buddy functionalities
- Add res cursor support for drm buddy

v2(Matthew Auld):
   - replace spinlock with mutex as we call kmem_cache_zalloc
 (..., GFP_KERNEL) in drm_buddy_alloc() function

   - lock drm_buddy_block_trim() function as it calls
 mark_free/mark_split are all globally visible

v3(Matthew Auld):
   - remove trim method error handling as we address the failure case
 at drm_buddy_block_trim() function

v4:
   - fix warnings reported by kernel test robot 

v5:
   - fix merge conflict issue

v6:
   - fix warnings reported by kernel test robot 

Signed-off-by: Arunpravin 
---
  drivers/gpu/drm/Kconfig   |   1 +
  .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
  4 files changed, 231 insertions(+), 133 deletions(-)




-/**
- * amdgpu_vram_mgr_virt_start - update virtual start address
- *
- * @mem: ttm_resource to update
- * @node: just allocated node
- *
- * Calculate a virtual BO start address to easily check if everything is CPU
- * accessible.
- */
-static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
-  struct drm_mm_node *node)
-{
-   unsigned long start;
-
-   start = node->start + node->size;
-   if (start > mem->num_pages)
-   start -= mem->num_pages;
-   else
-   start = 0;
-   mem->start = max(mem->start, start);
-}
-
  /**
   * amdgpu_vram_mgr_new - allocate new ranges
   *
@@ -366,13 +357,13 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
const struct ttm_place *place,
struct ttm_resource **res)
  {
-   unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
+   unsigned long lpfn, pages_per_node, pages_left, pages, n_pages;
+   u64 vis_usage = 0, mem_bytes, max_bytes, min_page_size;
 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 = >mm;
-   enum drm_mm_insert_mode mode;
+   struct amdgpu_vram_mgr_node *node;
+   struct drm_buddy *mm = >mm;
+   struct drm_buddy_block *block;
 unsigned i;
 int r;

@@ -391,10 +382,9 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,
 goto error_sub;
 }

-   if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
+   if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
 pages_per_node = ~0ul;
-   num_nodes = 1;
-   } else {
+   else {
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 pages_per_node = HPAGE_PMD_NR;
  #else
@@ -403,11 +393,9 @@ 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_ULL(PFN_UP(mem_bytes), pages_per_node);
 }

-   node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
-   GFP_KERNEL | __GFP_ZERO);
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
 if (!node) {
 r = -ENOMEM;
 goto error_sub;
@@ -415,9 +403,17 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager 
*man,

 ttm_resource_init(tbo, place, >base);

-   mode = DRM_MM_INSERT_BEST;
+   INIT_LIST_HEAD(>blocks);
+
 if (place->flags & TTM_PL_FLAG_TOPDOWN)
-   mode = DRM_MM_INSERT_HIGH;
+   node->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
+
+   if (place->fpfn || lpfn != man->size)
+   /* Allocate blocks in desired range */
+   node->flags |= DRM_BUDDY_RANGE_ALLOCATION;
+
+   min_page_size = mgr->default_page_size;
+   BUG_ON(min_page_size < mm->chunk_size);

 pages_left = node->base.num_pages;

@@ -425,36 +421,61 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,
 pages = min(pages_left, 2UL << (30 - PAGE_SHIFT));

 i = 0;
-   spin_lock(>lock);
 while (pages_left) {
-   uint32_t alignment = tbo->page_alignment;
-
 if (pages >= pages_per_node)
-   alignment = pages_per_node;
-
-   r = drm_mm_insert_node_in_range(mm, >mm_nodes[i], pages,
-   alignment, 0, place->fpfn,
-   lpfn, mode);
-   if (unlikely(r)) {
-   if (pages > pages_per_node) {
-  

Re: [PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-02-04 Thread Arunpravin



On 28/01/22 7:48 pm, Matthew Auld wrote:
> On Thu, 27 Jan 2022 at 14:11, Arunpravin
>  wrote:
>>
>> - Remove drm_mm references and replace with drm buddy functionalities
>> - Add res cursor support for drm buddy
>>
>> v2(Matthew Auld):
>>   - replace spinlock with mutex as we call kmem_cache_zalloc
>> (..., GFP_KERNEL) in drm_buddy_alloc() function
>>
>>   - lock drm_buddy_block_trim() function as it calls
>> mark_free/mark_split are all globally visible
>>
>> v3(Matthew Auld):
>>   - remove trim method error handling as we address the failure case
>> at drm_buddy_block_trim() function
>>
>> v4:
>>   - fix warnings reported by kernel test robot 
>>
>> v5:
>>   - fix merge conflict issue
>>
>> v6:
>>   - fix warnings reported by kernel test robot 
>>
>> Signed-off-by: Arunpravin 
>> ---
>>  drivers/gpu/drm/Kconfig   |   1 +
>>  .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
>>  4 files changed, 231 insertions(+), 133 deletions(-)
> 
> 
> 
>>
>> -/**
>> - * amdgpu_vram_mgr_virt_start - update virtual start address
>> - *
>> - * @mem: ttm_resource to update
>> - * @node: just allocated node
>> - *
>> - * Calculate a virtual BO start address to easily check if everything is CPU
>> - * accessible.
>> - */
>> -static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
>> -  struct drm_mm_node *node)
>> -{
>> -   unsigned long start;
>> -
>> -   start = node->start + node->size;
>> -   if (start > mem->num_pages)
>> -   start -= mem->num_pages;
>> -   else
>> -   start = 0;
>> -   mem->start = max(mem->start, start);
>> -}
>> -
>>  /**
>>   * amdgpu_vram_mgr_new - allocate new ranges
>>   *
>> @@ -366,13 +357,13 @@ static int amdgpu_vram_mgr_new(struct 
>> ttm_resource_manager *man,
>>const struct ttm_place *place,
>>struct ttm_resource **res)
>>  {
>> -   unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
>> +   unsigned long lpfn, pages_per_node, pages_left, pages, n_pages;
>> +   u64 vis_usage = 0, mem_bytes, max_bytes, min_page_size;
>> 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 = >mm;
>> -   enum drm_mm_insert_mode mode;
>> +   struct amdgpu_vram_mgr_node *node;
>> +   struct drm_buddy *mm = >mm;
>> +   struct drm_buddy_block *block;
>> unsigned i;
>> int r;
>>
>> @@ -391,10 +382,9 @@ static int amdgpu_vram_mgr_new(struct 
>> ttm_resource_manager *man,
>> goto error_sub;
>> }
>>
>> -   if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
>> +   if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
>> pages_per_node = ~0ul;
>> -   num_nodes = 1;
>> -   } else {
>> +   else {
>>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> pages_per_node = HPAGE_PMD_NR;
>>  #else
>> @@ -403,11 +393,9 @@ 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_ULL(PFN_UP(mem_bytes), 
>> pages_per_node);
>> }
>>
>> -   node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
>> -   GFP_KERNEL | __GFP_ZERO);
>> +   node = kzalloc(sizeof(*node), GFP_KERNEL);
>> if (!node) {
>> r = -ENOMEM;
>> goto error_sub;
>> @@ -415,9 +403,17 @@ static int amdgpu_vram_mgr_new(struct 
>> ttm_resource_manager *man,
>>
>> ttm_resource_init(tbo, place, >base);
>>
>> -   mode = DRM_MM_INSERT_BEST;
>> +   INIT_LIST_HEAD(>blocks);
>> +
>> if (place->flags & TTM_PL_FLAG_TOPDOWN)
>> -   mode = DRM_MM_INSERT_HIGH;
>> +   node->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
>> +
>> +   if (place->fpfn || lpfn != man->size)
>> +   /* Allocate blocks in desired range */
>> +   node->flags |= DRM_BUDDY_RANGE_ALLOCATION;
>> +
>> +   min_page_size = mgr->default_page_size;
>> +   BUG_ON(min_page_size < mm->chunk_size);
>>
>> pages_left = node->base.num_pages;
>>
>> @@ -425,36 +421,61 @@ static int amdgpu_vram_mgr_new(struct 
>> ttm_resource_manager *man,
>> pages = min(pages_left, 2UL << (30 - PAGE_SHIFT));
>>
>> i = 0;
>> -   spin_lock(>lock);
>> while (pages_left) {
>> -   uint32_t alignment = tbo->page_alignment;
>> -
>> if (pages >= pages_per_node)
>> -   alignment = pages_per_node;
>> 

Re: [PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-01-28 Thread Matthew Auld
On Thu, 27 Jan 2022 at 14:11, Arunpravin
 wrote:
>
> - Remove drm_mm references and replace with drm buddy functionalities
> - Add res cursor support for drm buddy
>
> v2(Matthew Auld):
>   - replace spinlock with mutex as we call kmem_cache_zalloc
> (..., GFP_KERNEL) in drm_buddy_alloc() function
>
>   - lock drm_buddy_block_trim() function as it calls
> mark_free/mark_split are all globally visible
>
> v3(Matthew Auld):
>   - remove trim method error handling as we address the failure case
> at drm_buddy_block_trim() function
>
> v4:
>   - fix warnings reported by kernel test robot 
>
> v5:
>   - fix merge conflict issue
>
> v6:
>   - fix warnings reported by kernel test robot 
>
> Signed-off-by: Arunpravin 
> ---
>  drivers/gpu/drm/Kconfig   |   1 +
>  .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
>  4 files changed, 231 insertions(+), 133 deletions(-)



>
> -/**
> - * amdgpu_vram_mgr_virt_start - update virtual start address
> - *
> - * @mem: ttm_resource to update
> - * @node: just allocated node
> - *
> - * Calculate a virtual BO start address to easily check if everything is CPU
> - * accessible.
> - */
> -static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
> -  struct drm_mm_node *node)
> -{
> -   unsigned long start;
> -
> -   start = node->start + node->size;
> -   if (start > mem->num_pages)
> -   start -= mem->num_pages;
> -   else
> -   start = 0;
> -   mem->start = max(mem->start, start);
> -}
> -
>  /**
>   * amdgpu_vram_mgr_new - allocate new ranges
>   *
> @@ -366,13 +357,13 @@ static int amdgpu_vram_mgr_new(struct 
> ttm_resource_manager *man,
>const struct ttm_place *place,
>struct ttm_resource **res)
>  {
> -   unsigned long lpfn, num_nodes, pages_per_node, pages_left, pages;
> +   unsigned long lpfn, pages_per_node, pages_left, pages, n_pages;
> +   u64 vis_usage = 0, mem_bytes, max_bytes, min_page_size;
> 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 = >mm;
> -   enum drm_mm_insert_mode mode;
> +   struct amdgpu_vram_mgr_node *node;
> +   struct drm_buddy *mm = >mm;
> +   struct drm_buddy_block *block;
> unsigned i;
> int r;
>
> @@ -391,10 +382,9 @@ static int amdgpu_vram_mgr_new(struct 
> ttm_resource_manager *man,
> goto error_sub;
> }
>
> -   if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
> +   if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
> pages_per_node = ~0ul;
> -   num_nodes = 1;
> -   } else {
> +   else {
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> pages_per_node = HPAGE_PMD_NR;
>  #else
> @@ -403,11 +393,9 @@ 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_ULL(PFN_UP(mem_bytes), 
> pages_per_node);
> }
>
> -   node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
> -   GFP_KERNEL | __GFP_ZERO);
> +   node = kzalloc(sizeof(*node), GFP_KERNEL);
> if (!node) {
> r = -ENOMEM;
> goto error_sub;
> @@ -415,9 +403,17 @@ static int amdgpu_vram_mgr_new(struct 
> ttm_resource_manager *man,
>
> ttm_resource_init(tbo, place, >base);
>
> -   mode = DRM_MM_INSERT_BEST;
> +   INIT_LIST_HEAD(>blocks);
> +
> if (place->flags & TTM_PL_FLAG_TOPDOWN)
> -   mode = DRM_MM_INSERT_HIGH;
> +   node->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
> +
> +   if (place->fpfn || lpfn != man->size)
> +   /* Allocate blocks in desired range */
> +   node->flags |= DRM_BUDDY_RANGE_ALLOCATION;
> +
> +   min_page_size = mgr->default_page_size;
> +   BUG_ON(min_page_size < mm->chunk_size);
>
> pages_left = node->base.num_pages;
>
> @@ -425,36 +421,61 @@ static int amdgpu_vram_mgr_new(struct 
> ttm_resource_manager *man,
> pages = min(pages_left, 2UL << (30 - PAGE_SHIFT));
>
> i = 0;
> -   spin_lock(>lock);
> while (pages_left) {
> -   uint32_t alignment = tbo->page_alignment;
> -
> if (pages >= pages_per_node)
> -   alignment = pages_per_node;
> -
> -   r = drm_mm_insert_node_in_range(mm, >mm_nodes[i], pages,
> -   alignment, 0, place->fpfn,
> - 

[PATCH v11 5/5] drm/amdgpu: add drm buddy support to amdgpu

2022-01-27 Thread Arunpravin
- Remove drm_mm references and replace with drm buddy functionalities
- Add res cursor support for drm buddy

v2(Matthew Auld):
  - replace spinlock with mutex as we call kmem_cache_zalloc
(..., GFP_KERNEL) in drm_buddy_alloc() function

  - lock drm_buddy_block_trim() function as it calls
mark_free/mark_split are all globally visible

v3(Matthew Auld):
  - remove trim method error handling as we address the failure case
at drm_buddy_block_trim() function

v4:
  - fix warnings reported by kernel test robot 

v5:
  - fix merge conflict issue

v6:
  - fix warnings reported by kernel test robot 

Signed-off-by: Arunpravin 
---
 drivers/gpu/drm/Kconfig   |   1 +
 .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h|  97 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   7 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c  | 259 ++
 4 files changed, 231 insertions(+), 133 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index dfdd3ec5f793..eb5a57ae3c5c 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -279,6 +279,7 @@ config DRM_AMDGPU
select HWMON
select BACKLIGHT_CLASS_DEVICE
select INTERVAL_TREE
+   select DRM_BUDDY
help
  Choose this option if you have a recent AMD Radeon graphics card.
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
index acfa207cf970..da12b4ff2e45 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
@@ -30,12 +30,15 @@
 #include 
 #include 
 
+#include "amdgpu_vram_mgr.h"
+
 /* state back for walking over vram_mgr and gtt_mgr allocations */
 struct amdgpu_res_cursor {
uint64_tstart;
uint64_tsize;
uint64_tremaining;
-   struct drm_mm_node  *node;
+   void*node;
+   uint32_tmem_type;
 };
 
 /**
@@ -52,27 +55,63 @@ static inline void amdgpu_res_first(struct ttm_resource 
*res,
uint64_t start, uint64_t size,
struct amdgpu_res_cursor *cur)
 {
+   struct drm_buddy_block *block;
+   struct list_head *head, *next;
struct drm_mm_node *node;
 
-   if (!res || res->mem_type == TTM_PL_SYSTEM) {
-   cur->start = start;
-   cur->size = size;
-   cur->remaining = size;
-   cur->node = NULL;
-   WARN_ON(res && start + size > res->num_pages << PAGE_SHIFT);
-   return;
-   }
+   if (!res)
+   goto err_out;
 
BUG_ON(start + size > res->num_pages << PAGE_SHIFT);
 
-   node = to_ttm_range_mgr_node(res)->mm_nodes;
-   while (start >= node->size << PAGE_SHIFT)
-   start -= node++->size << PAGE_SHIFT;
+   cur->mem_type = res->mem_type;
+
+   switch (cur->mem_type) {
+   case TTM_PL_VRAM:
+   head = _amdgpu_vram_mgr_node(res)->blocks;
+
+   block = list_first_entry_or_null(head,
+struct drm_buddy_block,
+link);
+   if (!block)
+   goto err_out;
+
+   while (start >= amdgpu_node_size(block)) {
+   start -= amdgpu_node_size(block);
+
+   next = block->link.next;
+   if (next != head)
+   block = list_entry(next, struct 
drm_buddy_block, link);
+   }
+
+   cur->start = amdgpu_node_start(block) + start;
+   cur->size = min(amdgpu_node_size(block) - start, size);
+   cur->remaining = size;
+   cur->node = block;
+   break;
+   case TTM_PL_TT:
+   node = to_ttm_range_mgr_node(res)->mm_nodes;
+   while (start >= node->size << PAGE_SHIFT)
+   start -= node++->size << PAGE_SHIFT;
+
+   cur->start = (node->start << PAGE_SHIFT) + start;
+   cur->size = min((node->size << PAGE_SHIFT) - start, size);
+   cur->remaining = size;
+   cur->node = node;
+   break;
+   default:
+   goto err_out;
+   }
 
-   cur->start = (node->start << PAGE_SHIFT) + start;
-   cur->size = min((node->size << PAGE_SHIFT) - start, size);
+   return;
+
+err_out:
+   cur->start = start;
+   cur->size = size;
cur->remaining = size;
-   cur->node = node;
+   cur->node = NULL;
+   WARN_ON(res && start + size > res->num_pages << PAGE_SHIFT);
+   return;
 }
 
 /**
@@ -85,7 +124,9 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
  */
 static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t 
size)
 {
-   struct drm_mm_node *node =