All of lore.kernel.org
 help / color / mirror / Atom feed
From: zhoucm1 <david1.zhou-5C7GfCeVMHo@public.gmane.org>
To: "Christian König"
	<deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [PATCH 6/6] drm/amdgpu: add VRAM manager v2
Date: Tue, 27 Sep 2016 17:57:52 +0800	[thread overview]
Message-ID: <57EA42A0.8020901@amd.com> (raw)
In-Reply-To: <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>



On 2016年09月27日 17:49, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Split VRAM allocations into 4MB blocks.
>
> v2: fix typo in comment, some suggested cleanups
> v3: document how to disable the feature, fix rebase issue
>
> 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_ttm.c      |   2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      |   1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++
>   7 files changed, 237 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 786b28a..2874bfe 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 73c9a2d..2a95827 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -99,6 +99,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 5ca6a38..d66a8df8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1053,6 +1053,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 08ba441..538d3a7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -84,6 +84,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;
> @@ -165,6 +166,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, -1 = disable)");
> +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
> +
>   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_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index bd377d8..588e242 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.
2016 is expected.

Regards,
David Zhou
> + *
> + * 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
> +};

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

  parent reply	other threads:[~2016-09-27  9:57 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 1/6] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS flag v3 Christian König
     [not found]     ` <1474969797-1882-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-10-07 21:19       ` Felix Kuehling
     [not found]         ` <627af621-8fb2-ba41-c87e-96bb12e594d8-5C7GfCeVMHo@public.gmane.org>
2016-10-11  9:35           ` Christian König
2016-09-27  9:49   ` [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS Christian König
2016-09-27  9:49   ` [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager Christian König
2016-09-27  9:49   ` [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 Christian König
2016-09-27  9:49   ` [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 Christian König
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 [this message]
2016-09-27 10:50   ` VRAM manager Mike Lothian
2016-09-27 11:17   ` Edward O'Callaghan
2016-10-07 22:11   ` Felix Kuehling
     [not found]     ` <ad665321-d00c-1ded-051f-2ca8eae014b4-5C7GfCeVMHo@public.gmane.org>
2016-10-11  9:34       ` Christian König
     [not found]         ` <6235e143-b44a-0039-b84c-c1be81de4a4c-5C7GfCeVMHo@public.gmane.org>
2016-10-11 18:59           ` Felix Kuehling
  -- strict thread matches above, loose matches on Subject: below --
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 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

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=57EA42A0.8020901@amd.com \
    --to=david1.zhou-5c7gfcevmho@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=deathsimple-ANTagKRnAhcb1SvskN2V4Q@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.