All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian König" <deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
To: Alex Deucher <alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: amd-gfx list <amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>
Subject: Re: [PATCH 6/6] drm/amdgpu: add VRAM manager v2
Date: Thu, 15 Sep 2016 19:42:16 +0200	[thread overview]
Message-ID: <fee0a492-6c88-e038-1a28-1812aa6ce9a4@vodafone.de> (raw)
In-Reply-To: <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Am 15.09.2016 um 16:44 schrieb Alex Deucher:
> On Thu, Sep 15, 2016 at 6:12 AM, Christian König
> <deathsimple@vodafone.de> wrote:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Split VRAM allocations into 4MB blocks.
>>
>> v2: fix typo in comment, some suggested cleanups
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/Makefile          |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu.h          |   1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   |   7 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c      |   4 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c   |   1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c      |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      |   1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++
>>   8 files changed, 238 insertions(+), 2 deletions(-)
>>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
>> index f2b97cb..236e9df 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>> @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>>          atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
>>          amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
>>          amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
>> -       amdgpu_gtt_mgr.o
>> +       amdgpu_gtt_mgr.o amdgpu_vram_mgr.o
>>
>>   # add asic specific block
>>   amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> index 588baaf..ee55763 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -98,6 +98,7 @@ extern char *amdgpu_disable_cu;
>>   extern int amdgpu_sclk_deep_sleep_en;
>>   extern char *amdgpu_virtual_display;
>>   extern unsigned amdgpu_pp_feature_mask;
>> +extern int amdgpu_vram_page_split;
>>
>>   #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS         3000
>>   #define AMDGPU_MAX_USEC_TIMEOUT                        100000  /* 100 ms */
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 5686d12..f26b067 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -1012,6 +1012,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
>>                           amdgpu_vm_block_size);
>>                  amdgpu_vm_block_size = 9;
>>          }
>> +
>> +       if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) ||
>> +           !amdgpu_check_pot_argument(amdgpu_vram_page_split)) {
>> +               dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
>> +                        amdgpu_vram_page_split);
>> +               amdgpu_vram_page_split = 1024;
>> +       }
>>   }
>>
>>   /**
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> index 902da13..44e605d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> @@ -83,6 +83,7 @@ int amdgpu_vm_size = 64;
>>   int amdgpu_vm_block_size = -1;
>>   int amdgpu_vm_fault_stop = 0;
>>   int amdgpu_vm_debug = 0;
>> +int amdgpu_vram_page_split = 1024;
>>   int amdgpu_exp_hw_support = 0;
>>   int amdgpu_dal = -1;
>>   int amdgpu_sched_jobs = 32;
>> @@ -164,6 +165,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
>>   MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)");
>>   module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
>>
>> +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)");
>> +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
> Not a big deal, but maybe make this unsigned instead of int?  I don't
> see any use for negative values.

-1 is used to disable the feature. I will update the parameter description.

Christian.

> Alex
>
>> +
>>   MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
>>   module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> index 03c6bfc..d6e6c93 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> @@ -970,6 +970,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>>          WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
>>          WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
>>                       !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS));
>> +       WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
>>
>>          return bo->tbo.offset;
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 4b8b39c..428ffb6 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
>>                  break;
>>          case TTM_PL_VRAM:
>>                  /* "On-card" video ram */
>> -               man->func = &ttm_bo_manager_func;
>> +               man->func = &amdgpu_vram_mgr_func;
>>                  man->gpu_offset = adev->mc.vram_start;
>>                  man->flags = TTM_MEMTYPE_FLAG_FIXED |
>>                               TTM_MEMTYPE_FLAG_MAPPABLE;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> index 9812c80..d1c00c0 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> @@ -66,6 +66,7 @@ struct amdgpu_mman {
>>   };
>>
>>   extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;
>> +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
>>
>>   int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
>>                           struct ttm_buffer_object *tbo,
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>> new file mode 100644
>> index 0000000..1125f7f
>> --- /dev/null
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>> @@ -0,0 +1,222 @@
>> +/*
>> + * Copyright 2015 Advanced Micro Devices, Inc.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
>> + * copy of this software and associated documentation files (the "Software"),
>> + * to deal in the Software without restriction, including without limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
>> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> + * OTHER DEALINGS IN THE SOFTWARE.
>> + *
>> + * Authors: Christian König
>> + */
>> +
>> +#include <drm/drmP.h>
>> +#include "amdgpu.h"
>> +
>> +struct amdgpu_vram_mgr {
>> +       struct drm_mm mm;
>> +       spinlock_t lock;
>> +};
>> +
>> +/**
>> + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM
>> + *
>> + * @man: TTM memory type manager
>> + * @p_size: maximum size of VRAM
>> + *
>> + * Allocate and initialize the VRAM manager.
>> + */
>> +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man,
>> +                               unsigned long p_size)
>> +{
>> +       struct amdgpu_vram_mgr *mgr;
>> +
>> +       mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
>> +       if (!mgr)
>> +               return -ENOMEM;
>> +
>> +       drm_mm_init(&mgr->mm, 0, p_size);
>> +       spin_lock_init(&mgr->lock);
>> +       man->priv = mgr;
>> +       return 0;
>> +}
>> +
>> +/**
>> + * amdgpu_vram_mgr_fini - free and destroy VRAM manager
>> + *
>> + * @man: TTM memory type manager
>> + *
>> + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still
>> + * allocated inside it.
>> + */
>> +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
>> +{
>> +       struct amdgpu_vram_mgr *mgr = man->priv;
>> +
>> +       spin_lock(&mgr->lock);
>> +       if (!drm_mm_clean(&mgr->mm)) {
>> +               spin_unlock(&mgr->lock);
>> +               return -EBUSY;
>> +       }
>> +
>> +       drm_mm_takedown(&mgr->mm);
>> +       spin_unlock(&mgr->lock);
>> +       kfree(mgr);
>> +       man->priv = NULL;
>> +       return 0;
>> +}
>> +
>> +/**
>> + * amdgpu_vram_mgr_new - allocate new ranges
>> + *
>> + * @man: TTM memory type manager
>> + * @tbo: TTM BO we need this range for
>> + * @place: placement flags and restrictions
>> + * @mem: the resulting mem object
>> + *
>> + * Allocate VRAM for the given BO.
>> + */
>> +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
>> +                              struct ttm_buffer_object *tbo,
>> +                              const struct ttm_place *place,
>> +                              struct ttm_mem_reg *mem)
>> +{
>> +       struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo);
>> +       struct amdgpu_vram_mgr *mgr = man->priv;
>> +       struct drm_mm *mm = &mgr->mm;
>> +       struct drm_mm_node *nodes;
>> +       enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
>> +       enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
>> +       unsigned long lpfn, num_nodes, pages_per_node, pages_left;
>> +       unsigned i;
>> +       int r;
>> +
>> +       lpfn = place->lpfn;
>> +       if (!lpfn)
>> +               lpfn = man->size;
>> +
>> +       if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS ||
>> +           amdgpu_vram_page_split == -1) {
>> +               pages_per_node = ~0ul;
>> +               num_nodes = 1;
>> +       } else {
>> +               pages_per_node = max((uint32_t)amdgpu_vram_page_split,
>> +                                    mem->page_alignment);
>> +               num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
>> +       }
>> +
>> +       nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL);
>> +       if (!nodes)
>> +               return -ENOMEM;
>> +
>> +       if (place->flags & TTM_PL_FLAG_TOPDOWN) {
>> +               sflags = DRM_MM_SEARCH_BELOW;
>> +               aflags = DRM_MM_CREATE_TOP;
>> +       }
>> +
>> +       pages_left = mem->num_pages;
>> +
>> +       spin_lock(&mgr->lock);
>> +       for (i = 0; i < num_nodes; ++i) {
>> +               unsigned long pages = min(pages_left, pages_per_node);
>> +               uint32_t alignment = mem->page_alignment;
>> +
>> +               if (pages == pages_per_node)
>> +                       alignment = pages_per_node;
>> +               else
>> +                       sflags |= DRM_MM_SEARCH_BEST;
>> +
>> +               r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages,
>> +                                                       alignment, 0,
>> +                                                       place->fpfn, lpfn,
>> +                                                       sflags, aflags);
>> +               if (unlikely(r))
>> +                       goto error;
>> +
>> +               pages_left -= pages;
>> +       }
>> +       spin_unlock(&mgr->lock);
>> +
>> +       mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET;
>> +       mem->mm_node = nodes;
>> +
>> +       return 0;
>> +
>> +error:
>> +       while (i--)
>> +               drm_mm_remove_node(&nodes[i]);
>> +       spin_unlock(&mgr->lock);
>> +
>> +       kfree(nodes);
>> +       return r == -ENOSPC ? 0 : r;
>> +}
>> +
>> +/**
>> + * amdgpu_vram_mgr_del - free ranges
>> + *
>> + * @man: TTM memory type manager
>> + * @tbo: TTM BO we need this range for
>> + * @place: placement flags and restrictions
>> + * @mem: TTM memory object
>> + *
>> + * Free the allocated VRAM again.
>> + */
>> +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
>> +                               struct ttm_mem_reg *mem)
>> +{
>> +       struct amdgpu_vram_mgr *mgr = man->priv;
>> +       struct drm_mm_node *nodes = mem->mm_node;
>> +       unsigned pages = mem->num_pages;
>> +
>> +       if (!mem->mm_node)
>> +               return;
>> +
>> +       spin_lock(&mgr->lock);
>> +       while (pages) {
>> +               pages -= nodes->size;
>> +               drm_mm_remove_node(nodes);
>> +               ++nodes;
>> +       }
>> +       spin_unlock(&mgr->lock);
>> +
>> +       kfree(mem->mm_node);
>> +       mem->mm_node = NULL;
>> +}
>> +
>> +/**
>> + * amdgpu_vram_mgr_debug - dump VRAM table
>> + *
>> + * @man: TTM memory type manager
>> + * @prefix: text prefix
>> + *
>> + * Dump the table content using printk.
>> + */
>> +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
>> +                                 const char *prefix)
>> +{
>> +       struct amdgpu_vram_mgr *mgr = man->priv;
>> +
>> +       spin_lock(&mgr->lock);
>> +       drm_mm_debug_table(&mgr->mm, prefix);
>> +       spin_unlock(&mgr->lock);
>> +}
>> +
>> +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
>> +       amdgpu_vram_mgr_init,
>> +       amdgpu_vram_mgr_fini,
>> +       amdgpu_vram_mgr_new,
>> +       amdgpu_vram_mgr_del,
>> +       amdgpu_vram_mgr_debug
>> +};
>> --
>> 2.5.0
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2016-09-15 17:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-15 10:12 [PATCH 1/6] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS flag v3 Christian König
     [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-09-15 10:12   ` [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS Christian König
2016-09-15 10:12   ` [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager Christian König
2016-09-15 10:12   ` [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 Christian König
2016-09-15 10:12   ` [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 Christian König
2016-09-15 10:12   ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König
     [not found]     ` <1473934344-2106-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-09-15 14:44       ` Alex Deucher
     [not found]         ` <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-09-15 17:42           ` Christian König [this message]
2016-09-27  9:49 VRAM manager Christian König
     [not found] ` <1474969797-1882-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-09-27  9:49   ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König
     [not found]     ` <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-09-27  9:57       ` zhoucm1

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fee0a492-6c88-e038-1a28-1812aa6ce9a4@vodafone.de \
    --to=deathsimple-antagkrnahcb1svskn2v4q@public.gmane.org \
    --cc=alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.