[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <3246ca6a-0ccc-4d5e-b5ff-f23fafe39c00@amd.com>
Date: Fri, 21 Nov 2025 14:50:27 +0100
From: Christian König <christian.koenig@....com>
To: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@....com>,
Alex Deucher <alexander.deucher@....com>, David Airlie <airlied@...il.com>,
Simona Vetter <simona@...ll.ch>
Cc: amd-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 12/28] drm/amdgpu: remove
AMDGPU_GTT_NUM_TRANSFER_WINDOWS
On 11/21/25 11:12, Pierre-Eric Pelloux-Prayer wrote:
> ttm is going to use a variable number of windows so we need to get
> rid of the hardcoded value.
>
> Since amdgpu_gtt_mgr_init is initialized after
> amdgpu_ttm_set_buffer_funcs_status is called with enable=false, we
> still need to determine the reserved windows count before doing
> the real initialisation so a warning is added if the actual value
> doesn't match the reserved one.
Reading that I just realized that we have a chicken and egg problem here.
When initializing the driver we know the maximum number of SDMA engines we might see, but we don't know if all of them are working.
So we need to initialize the GART and GTT manager to bringup and test each SDMA engine before we can figure out how many GART windows we need.
*sigh* We probably need to re-iterate over the idea of dynamical allocation of GART windows.
It's most likely not a problem for current production HW, but most likely become one sooner or later.
Should we clean that up now or postpone till later?
Regards,
Christian.
>
> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@....com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 8 +++++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 21 ++++++++++++++-------
> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 7 +++----
> drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 6 ++++--
> drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 3 ++-
> drivers/gpu/drm/amd/amdgpu/vce_v1_0.c | 12 ++++--------
> 6 files changed, 32 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> index 895c1e4c6747..924151b6cfd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> @@ -269,10 +269,12 @@ static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
> *
> * @adev: amdgpu_device pointer
> * @gtt_size: maximum size of GTT
> + * @reserved_windows: num of already used windows
> *
> * Allocate and initialize the GTT manager.
> */
> -int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
> +int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size,
> + u32 reserved_windows)
> {
> struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
> struct ttm_resource_manager *man = &mgr->manager;
> @@ -283,8 +285,8 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
>
> ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
>
> - start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
> - start += amdgpu_vce_required_gart_pages(adev);
> + start = AMDGPU_GTT_MAX_TRANSFER_SIZE * reserved_windows;
> + start += amdgpu_vce_required_gart_pages(adev, start);
> size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
> drm_mm_init(&mgr->mm, start, size);
> spin_lock_init(&mgr->lock);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 1371a40d4687..3a0511d1739f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1907,6 +1907,7 @@ static int amdgpu_ttm_buffer_entity_init(struct amdgpu_ttm_buffer_entity *entity
> int amdgpu_ttm_init(struct amdgpu_device *adev)
> {
> uint64_t gtt_size;
> + u32 reserved_windows;
> int r;
>
> dma_set_max_seg_size(adev->dev, UINT_MAX);
> @@ -1939,7 +1940,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
> }
>
> /* Change the size here instead of the init above so only lpfn is affected */
> - amdgpu_ttm_set_buffer_funcs_status(adev, false);
> + reserved_windows = amdgpu_ttm_set_buffer_funcs_status(adev, false);
> #ifdef CONFIG_64BIT
> #ifdef CONFIG_X86
> if (adev->gmc.xgmi.connected_to_cpu)
> @@ -2035,7 +2036,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
> }
>
> /* Initialize GTT memory pool */
> - r = amdgpu_gtt_mgr_init(adev, gtt_size);
> + r = amdgpu_gtt_mgr_init(adev, gtt_size, reserved_windows);
> if (r) {
> dev_err(adev->dev, "Failed initializing GTT heap.\n");
> return r;
> @@ -2174,17 +2175,21 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
> *
> * Enable/disable use of buffer functions during suspend/resume. This should
> * only be called at bootup or when userspace isn't running.
> + *
> + * Returns: the number of GART reserved window
> */
> -void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> +u32 amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> {
> struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
> - u32 used_windows;
> + u32 used_windows, reserved_windows;
> uint64_t size;
> int r;
>
> + reserved_windows = 3;
> +
> if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
> adev->mman.buffer_funcs_enabled == enable || adev->gmc.is_app_apu)
> - return;
> + return reserved_windows;
>
> if (enable) {
> struct amdgpu_ring *ring;
> @@ -2199,7 +2204,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> dev_err(adev->dev,
> "Failed setting up TTM BO move entity (%d)\n",
> r);
> - return;
> + return 0;
> }
>
> r = drm_sched_entity_init(&adev->mman.clear_entity.base,
> @@ -2230,6 +2235,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> used_windows, true, true);
> used_windows = amdgpu_ttm_buffer_entity_init(&adev->mman.clear_entity,
> used_windows, false, true);
> + WARN_ON(used_windows != reserved_windows);
> } else {
> drm_sched_entity_destroy(&adev->mman.default_entity.base);
> drm_sched_entity_destroy(&adev->mman.clear_entity.base);
> @@ -2248,10 +2254,11 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
> man->size = size;
> adev->mman.buffer_funcs_enabled = enable;
>
> - return;
> + return reserved_windows;
>
> error_free_entity:
> drm_sched_entity_destroy(&adev->mman.default_entity.base);
> + return 0;
> }
>
> static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index a7eed678bd3f..2a78cf8a3f9f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -40,7 +40,6 @@
> #define __AMDGPU_PL_NUM (TTM_PL_PRIV + 6)
>
> #define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
> -#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 3
>
> extern const struct attribute_group amdgpu_vram_mgr_attr_group;
> extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
> @@ -134,7 +133,7 @@ struct amdgpu_copy_mem {
> #define AMDGPU_COPY_FLAGS_GET(value, field) \
> (((__u32)(value) >> AMDGPU_COPY_FLAGS_##field##_SHIFT) & AMDGPU_COPY_FLAGS_##field##_MASK)
>
> -int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size);
> +int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size, u32 reserved_windows);
> void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev);
> int amdgpu_preempt_mgr_init(struct amdgpu_device *adev);
> void amdgpu_preempt_mgr_fini(struct amdgpu_device *adev);
> @@ -168,8 +167,8 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
>
> int amdgpu_ttm_init(struct amdgpu_device *adev);
> void amdgpu_ttm_fini(struct amdgpu_device *adev);
> -void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
> - bool enable);
> +u32 amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
> + bool enable);
> int amdgpu_copy_buffer(struct amdgpu_device *adev,
> struct amdgpu_ttm_buffer_entity *entity,
> uint64_t src_offset,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index a7d8f1ce6ac2..56308efce465 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -459,11 +459,13 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
> * For VCE1, see vce_v1_0_ensure_vcpu_bo_32bit_addr for details.
> * For VCE2+, this is not needed so return zero.
> */
> -u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev)
> +u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev, u64 gtt_transfer_end)
> {
> /* VCE IP block not added yet, so can't use amdgpu_ip_version */
> - if (adev->family == AMDGPU_FAMILY_SI)
> + if (adev->family == AMDGPU_FAMILY_SI) {
> + adev->vce.gart_page_start = gtt_transfer_end;
> return 512;
> + }
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> index 1c3464ce5037..d07302535d33 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
> @@ -52,6 +52,7 @@ struct amdgpu_vce {
> uint32_t srbm_soft_reset;
> unsigned num_rings;
> uint32_t keyselect;
> + u64 gart_page_start;
> };
>
> int amdgpu_vce_early_init(struct amdgpu_device *adev);
> @@ -61,7 +62,7 @@ int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring)
> int amdgpu_vce_suspend(struct amdgpu_device *adev);
> int amdgpu_vce_resume(struct amdgpu_device *adev);
> void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
> -u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev);
> +u32 amdgpu_vce_required_gart_pages(struct amdgpu_device *adev, u64 gtt_transfer_end);
> int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
> struct amdgpu_ib *ib);
> int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p,
> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v1_0.c
> index 9ae424618556..dd18fc45225d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vce_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v1_0.c
> @@ -47,11 +47,6 @@
> #define VCE_V1_0_DATA_SIZE (7808 * (AMDGPU_MAX_VCE_HANDLES + 1))
> #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
>
> -#define VCE_V1_0_GART_PAGE_START \
> - (AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS)
> -#define VCE_V1_0_GART_ADDR_START \
> - (VCE_V1_0_GART_PAGE_START * AMDGPU_GPU_PAGE_SIZE)
> -
> static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev);
> static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev);
>
> @@ -541,6 +536,7 @@ static int vce_v1_0_ensure_vcpu_bo_32bit_addr(struct amdgpu_device *adev)
> u64 num_pages = ALIGN(bo_size, AMDGPU_GPU_PAGE_SIZE) / AMDGPU_GPU_PAGE_SIZE;
> u64 pa = amdgpu_gmc_vram_pa(adev, adev->vce.vcpu_bo);
> u64 flags = AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | AMDGPU_PTE_VALID;
> + u64 vce_gart_addr_start = adev->vce.gart_page_start * AMDGPU_GPU_PAGE_SIZE;
>
> /*
> * Check if the VCPU BO already has a 32-bit address.
> @@ -550,12 +546,12 @@ static int vce_v1_0_ensure_vcpu_bo_32bit_addr(struct amdgpu_device *adev)
> return 0;
>
> /* Check if we can map the VCPU BO in GART to a 32-bit address. */
> - if (adev->gmc.gart_start + VCE_V1_0_GART_ADDR_START > max_vcpu_bo_addr)
> + if (adev->gmc.gart_start + vce_gart_addr_start > max_vcpu_bo_addr)
> return -EINVAL;
>
> - amdgpu_gart_map_vram_range(adev, pa, VCE_V1_0_GART_PAGE_START,
> + amdgpu_gart_map_vram_range(adev, pa, adev->vce.gart_page_start,
> num_pages, flags, adev->gart.ptr);
> - adev->vce.gpu_addr = adev->gmc.gart_start + VCE_V1_0_GART_ADDR_START;
> + adev->vce.gpu_addr = adev->gmc.gart_start + vce_gart_addr_start;
> if (adev->vce.gpu_addr > max_vcpu_bo_addr)
> return -EINVAL;
>
Powered by blists - more mailing lists