All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2)
@ 2026-05-25 11:33 Timur Kristóf
  2026-05-25 11:33 ` [PATCH 1/4] drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions Timur Kristóf
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Timur Kristóf @ 2026-05-25 11:33 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, christian.koenig, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam
  Cc: Timur Kristóf

UVD 4.x and older have two requirements for CS BOs:
1. All BOs must not cross 256M segments
2. MSG and FB BOs must be located in the same segment as the VCPU BO

The amdgpu_uvd code attempts to solve those requirements,
but unfortunately it has hit various limitations:

* VCPU BO may be placed in a different segment
* GTT manager doesn't respect placement requirements
* GTT allocations may cross 256M
* GTT->GTT moves are not implemented

Let's solve these issues by fixing the GTT manager,
making sure that GTT allocations are placed in 256M segments.
Also fix forcing MSG and FB BOs to the UVD segment
when the UVD segment isn't the first segment, which can be
the case when resizable BAR is enabled.

This series should be backported to 7.0 and 7.1 because
technically this may have been a regression for some users
caused by switching to amdgpu by default.

Changes in v2:

* Fix GTT->GTT moves instead of specifying a placement in
  the amdgpu_ttm_alloc_gart() function.
* Move MSG and FB BOs to the VCPU segments, leave all other
  BOs in segment 0 like before.

Timur Kristóf (4):
  drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions
  drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT
  drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older
  drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it
    isn't at 0 (v2)

 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 30 ++++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 18 ++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c     | 50 ++++++++++++++-------
 3 files changed, 81 insertions(+), 17 deletions(-)

-- 
2.54.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions
  2026-05-25 11:33 [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2) Timur Kristóf
@ 2026-05-25 11:33 ` Timur Kristóf
  2026-05-25 11:33 ` [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT Timur Kristóf
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Timur Kristóf @ 2026-05-25 11:33 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, christian.koenig, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam
  Cc: Timur Kristóf

When testing intersection and compatibility, respect
the actual placement requirements. This is a pre-requisite
for ensuring that UVD CS BOs do not cross 256M segments.

Fixes: ded910f368a5 ("drm/amdgpu: Implement intersect/compatible functions")
Suggested-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 30 +++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 02f85802f579..19b6770a877d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -272,7 +272,20 @@ static bool amdgpu_gtt_mgr_intersects(struct ttm_resource_manager *man,
 				      const struct ttm_place *place,
 				      size_t size)
 {
-	return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
+	const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
+	const u32 num_pages = PFN_UP(size);
+
+	if (!place->lpfn)
+		return true;
+
+	if (!amdgpu_gtt_mgr_has_gart_addr(res))
+		return false;
+
+	if (place->fpfn >= (node->start + num_pages) ||
+	    (place->lpfn && place->lpfn <= node->start))
+		return false;
+
+	return true;
 }
 
 /**
@@ -290,7 +303,20 @@ static bool amdgpu_gtt_mgr_compatible(struct ttm_resource_manager *man,
 				      const struct ttm_place *place,
 				      size_t size)
 {
-	return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
+	const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
+	const u32 num_pages = PFN_UP(size);
+
+	if (!place->lpfn)
+		return true;
+
+	if (!amdgpu_gtt_mgr_has_gart_addr(res))
+		return false;
+
+	if (node->start < place->fpfn ||
+	    (place->lpfn && (node->start + num_pages) > place->lpfn))
+		return false;
+
+	return true;
 }
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT
  2026-05-25 11:33 [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2) Timur Kristóf
  2026-05-25 11:33 ` [PATCH 1/4] drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions Timur Kristóf
@ 2026-05-25 11:33 ` Timur Kristóf
  2026-05-26  8:07   ` Christian König
  2026-05-25 11:33 ` [PATCH 3/4] drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older Timur Kristóf
  2026-05-25 11:33 ` [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2) Timur Kristóf
  3 siblings, 1 reply; 9+ messages in thread
From: Timur Kristóf @ 2026-05-25 11:33 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, christian.koenig, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam
  Cc: Timur Kristóf

The UVD code relies on GTT to GTT moves in order to ensure
that its BOs don't cross 256M segments.

Fixes: bfe5e585b44f ("drm/ttm: move last binding into the drivers.")
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 6c6ab4dd6ea9..f80371bc74d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -515,6 +515,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
 
 	if (new_mem->mem_type == TTM_PL_TT ||
 	    new_mem->mem_type == AMDGPU_PL_PREEMPT) {
+		if (old_mem && (old_mem->mem_type == TTM_PL_TT ||
+				old_mem->mem_type == AMDGPU_PL_PREEMPT)) {
+			r = ttm_bo_wait_ctx(bo, ctx);
+			if (r)
+				return r;
+
+			amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
+		}
+
 		r = amdgpu_ttm_backend_bind(bo->bdev, bo->ttm, new_mem);
 		if (r)
 			return r;
@@ -549,6 +558,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
 		ttm_bo_assign_mem(bo, new_mem);
 		return 0;
 	}
+	if ((old_mem->mem_type == TTM_PL_TT ||
+	     old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
+	    (new_mem->mem_type == TTM_PL_TT ||
+	     new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
+		amdgpu_bo_move_notify(bo, evict, new_mem);
+		ttm_resource_free(bo, &bo->resource);
+		ttm_bo_assign_mem(bo, new_mem);
+		return 0;
+	}
 
 	if (old_mem->mem_type == AMDGPU_PL_GDS ||
 	    old_mem->mem_type == AMDGPU_PL_GWS ||
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older
  2026-05-25 11:33 [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2) Timur Kristóf
  2026-05-25 11:33 ` [PATCH 1/4] drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions Timur Kristóf
  2026-05-25 11:33 ` [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT Timur Kristóf
@ 2026-05-25 11:33 ` Timur Kristóf
  2026-05-25 11:33 ` [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2) Timur Kristóf
  3 siblings, 0 replies; 9+ messages in thread
From: Timur Kristóf @ 2026-05-25 11:33 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, christian.koenig, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam
  Cc: Timur Kristóf

These UVD versions don't fully support GPUVM and are only
validated to work when their VCPU BO is placed in VRAM.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 3a3bc0d370fa..1e59ca924abe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -188,6 +188,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
 	const struct common_firmware_header *hdr;
 	unsigned int family_id;
 	int i, j, r;
+	u32 vcpu_bo_domain;
 
 	INIT_DELAYED_WORK(&adev->uvd.idle_work, amdgpu_uvd_idle_work_handler);
 
@@ -319,12 +320,20 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
 		bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
 
+	/* UVD 5.0 and newer HW can use 64 bit addressing. */
+	adev->uvd.address_64_bit =
+		!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0);
+
+	vcpu_bo_domain = AMDGPU_GEM_DOMAIN_VRAM;
+	if (adev->uvd.address_64_bit)
+		vcpu_bo_domain |= AMDGPU_GEM_DOMAIN_GTT;
+
 	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
 		if (adev->uvd.harvest_config & (1 << j))
 			continue;
+
 		r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
-					    AMDGPU_GEM_DOMAIN_VRAM |
-					    AMDGPU_GEM_DOMAIN_GTT,
+					    vcpu_bo_domain,
 					    &adev->uvd.inst[j].vcpu_bo,
 					    &adev->uvd.inst[j].gpu_addr,
 					    &adev->uvd.inst[j].cpu_addr);
@@ -339,10 +348,6 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
 		adev->uvd.filp[i] = NULL;
 	}
 
-	/* from uvd v5.0 HW addressing capacity increased to 64 bits */
-	if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
-		adev->uvd.address_64_bit = true;
-
 	r = amdgpu_uvd_create_msg_bo_helper(adev, 128 << 10, &adev->uvd.ib_bo);
 	if (r)
 		return r;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)
  2026-05-25 11:33 [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2) Timur Kristóf
                   ` (2 preceding siblings ...)
  2026-05-25 11:33 ` [PATCH 3/4] drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older Timur Kristóf
@ 2026-05-25 11:33 ` Timur Kristóf
  2026-05-26  8:10   ` Christian König
  3 siblings, 1 reply; 9+ messages in thread
From: Timur Kristóf @ 2026-05-25 11:33 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, christian.koenig, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam
  Cc: Timur Kristóf

UVD 4.x and older can only access MSG, FEEDBACK buffers from a
specific 256M VRAM segment that the VCPU BO is also located in.
We already modify all placements of the given BO to ensure
the BO is placed within this segment.

Previously, it always assumed that the VCPU segment is
the first 256M of VRAM, even though under some conditions
the VCPU BO could be allocated outside this segment,
which made UVD non-functional as the BOs were
not inside the same segment as the UVD VCPU BO.

Solve that by using the segment where the VCPU BO actually is.

This fixes an issue with UVD failing to initialize on SI/CIK
when resizable BAR is enabled and the VCPU BO is allocated
in a different segment.

v2:
- For other BOs, keep using the same UVD segment as before.

Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3851
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 33 ++++++++++++++++++-------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 1e59ca924abe..480bf88def46 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -135,7 +135,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12);
 MODULE_FIRMWARE(FIRMWARE_VEGA20);
 
 static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
-static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo);
+static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *abo);
 
 static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
 					   uint32_t size,
@@ -158,7 +158,7 @@ static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
 	amdgpu_bo_kunmap(bo);
 	amdgpu_bo_unpin(bo);
 	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
-	amdgpu_uvd_force_into_uvd_segment(bo);
+	amdgpu_uvd_force_into_vcpu_segment(bo);
 	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
 	if (r)
 		goto err;
@@ -550,6 +550,24 @@ void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
 	}
 }
 
+static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *bo)
+{
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+	struct amdgpu_bo *vcpu_bo = adev->uvd.inst[0].vcpu_bo;
+	struct amdgpu_res_cursor vcpu_cur;
+
+	amdgpu_res_first(vcpu_bo->tbo.resource, 0,
+			 amdgpu_bo_size(vcpu_bo), &vcpu_cur);
+
+	bo->placement.num_placement = 1;
+	bo->placement.placement = &bo->placements[0];
+	bo->placements[0].fpfn = ALIGN_DOWN(vcpu_cur.start, SZ_256M) >> PAGE_SHIFT;
+	bo->placements[0].lpfn = bo->placements[0].fpfn + (SZ_256M >> PAGE_SHIFT);
+	bo->placements[0].mem_type = vcpu_bo->tbo.resource->mem_type;
+	if (bo->placements[0].mem_type == TTM_PL_VRAM)
+		bo->placements[0].flags |= TTM_PL_FLAG_CONTIGUOUS;
+}
+
 static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo)
 {
 	int i;
@@ -600,13 +618,10 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
 	if (!ctx->parser->adev->uvd.address_64_bit) {
 		/* check if it's a message or feedback command */
 		cmd = amdgpu_ib_get_value(ctx->ib, ctx->idx) >> 1;
-		if (cmd == 0x0 || cmd == 0x3) {
-			/* yes, force it into VRAM */
-			uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
-
-			amdgpu_bo_placement_from_domain(bo, domain);
-		}
-		amdgpu_uvd_force_into_uvd_segment(bo);
+		if (cmd == 0x0 || cmd == 0x3)
+			amdgpu_uvd_force_into_vcpu_segment(bo);
+		else
+			amdgpu_uvd_force_into_uvd_segment(bo);
 
 		r = ttm_bo_validate(&bo->tbo, &bo->placement, &tctx);
 	}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT
  2026-05-25 11:33 ` [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT Timur Kristóf
@ 2026-05-26  8:07   ` Christian König
  0 siblings, 0 replies; 9+ messages in thread
From: Christian König @ 2026-05-26  8:07 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx, Alex Deucher, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam

On 5/25/26 13:33, Timur Kristóf wrote:
> The UVD code relies on GTT to GTT moves in order to ensure
> that its BOs don't cross 256M segments.
> 
> Fixes: bfe5e585b44f ("drm/ttm: move last binding into the drivers.")
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 6c6ab4dd6ea9..f80371bc74d7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -515,6 +515,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>  
>  	if (new_mem->mem_type == TTM_PL_TT ||
>  	    new_mem->mem_type == AMDGPU_PL_PREEMPT) {
> +		if (old_mem && (old_mem->mem_type == TTM_PL_TT ||
> +				old_mem->mem_type == AMDGPU_PL_PREEMPT)) {
> +			r = ttm_bo_wait_ctx(bo, ctx);
> +			if (r)
> +				return r;
> +
> +			amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
> +		}
> +
>  		r = amdgpu_ttm_backend_bind(bo->bdev, bo->ttm, new_mem);
>  		if (r)
>  			return r;
> @@ -549,6 +558,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>  		ttm_bo_assign_mem(bo, new_mem);
>  		return 0;
>  	}
> +	if ((old_mem->mem_type == TTM_PL_TT ||
> +	     old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
> +	    (new_mem->mem_type == TTM_PL_TT ||
> +	     new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
> +		amdgpu_bo_move_notify(bo, evict, new_mem);
> +		ttm_resource_free(bo, &bo->resource);
> +		ttm_bo_assign_mem(bo, new_mem);
> +		return 0;
> +	}
>  
>  	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>  	    old_mem->mem_type == AMDGPU_PL_GWS ||


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)
  2026-05-25 11:33 ` [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2) Timur Kristóf
@ 2026-05-26  8:10   ` Christian König
  2026-05-26 10:13     ` Timur Kristóf
  0 siblings, 1 reply; 9+ messages in thread
From: Christian König @ 2026-05-26  8:10 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx, Alex Deucher, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam



On 5/25/26 13:33, Timur Kristóf wrote:
> UVD 4.x and older can only access MSG, FEEDBACK buffers from a
> specific 256M VRAM segment that the VCPU BO is also located in.
> We already modify all placements of the given BO to ensure
> the BO is placed within this segment.
> 
> Previously, it always assumed that the VCPU segment is
> the first 256M of VRAM, even though under some conditions
> the VCPU BO could be allocated outside this segment,
> which made UVD non-functional as the BOs were
> not inside the same segment as the UVD VCPU BO.
> 
> Solve that by using the segment where the VCPU BO actually is.
> 
> This fixes an issue with UVD failing to initialize on SI/CIK
> when resizable BAR is enabled and the VCPU BO is allocated
> in a different segment.
> 
> v2:
> - For other BOs, keep using the same UVD segment as before.
> 
> Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3851
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 33 ++++++++++++++++++-------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> index 1e59ca924abe..480bf88def46 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> @@ -135,7 +135,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12);
>  MODULE_FIRMWARE(FIRMWARE_VEGA20);
>  
>  static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
> -static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo);
> +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *abo);
>  
>  static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
>  					   uint32_t size,
> @@ -158,7 +158,7 @@ static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
>  	amdgpu_bo_kunmap(bo);
>  	amdgpu_bo_unpin(bo);
>  	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
> -	amdgpu_uvd_force_into_uvd_segment(bo);
> +	amdgpu_uvd_force_into_vcpu_segment(bo);
>  	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
>  	if (r)
>  		goto err;
> @@ -550,6 +550,24 @@ void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
>  	}
>  }
>  
> +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *bo)
> +{
> +	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
> +	struct amdgpu_bo *vcpu_bo = adev->uvd.inst[0].vcpu_bo;
> +	struct amdgpu_res_cursor vcpu_cur;
> +
> +	amdgpu_res_first(vcpu_bo->tbo.resource, 0,
> +			 amdgpu_bo_size(vcpu_bo), &vcpu_cur);
> +
> +	bo->placement.num_placement = 1;
> +	bo->placement.placement = &bo->placements[0];
> +	bo->placements[0].fpfn = ALIGN_DOWN(vcpu_cur.start, SZ_256M) >> PAGE_SHIFT;
> +	bo->placements[0].lpfn = bo->placements[0].fpfn + (SZ_256M >> PAGE_SHIFT);
> +	bo->placements[0].mem_type = vcpu_bo->tbo.resource->mem_type;
> +	if (bo->placements[0].mem_type == TTM_PL_VRAM)
> +		bo->placements[0].flags |= TTM_PL_FLAG_CONTIGUOUS;

You need to call ttm_bo_validate() here.

Apart from that looks good to me.

Regards,
Christian


> +}
> +
>  static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo)
>  {
>  	int i;
> @@ -600,13 +618,10 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
>  	if (!ctx->parser->adev->uvd.address_64_bit) {
>  		/* check if it's a message or feedback command */
>  		cmd = amdgpu_ib_get_value(ctx->ib, ctx->idx) >> 1;
> -		if (cmd == 0x0 || cmd == 0x3) {
> -			/* yes, force it into VRAM */
> -			uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
> -
> -			amdgpu_bo_placement_from_domain(bo, domain);
> -		}
> -		amdgpu_uvd_force_into_uvd_segment(bo);
> +		if (cmd == 0x0 || cmd == 0x3)
> +			amdgpu_uvd_force_into_vcpu_segment(bo);
> +		else
> +			amdgpu_uvd_force_into_uvd_segment(bo);
>  
>  		r = ttm_bo_validate(&bo->tbo, &bo->placement, &tctx);
>  	}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)
  2026-05-26  8:10   ` Christian König
@ 2026-05-26 10:13     ` Timur Kristóf
  2026-05-26 10:46       ` Christian König
  0 siblings, 1 reply; 9+ messages in thread
From: Timur Kristóf @ 2026-05-26 10:13 UTC (permalink / raw)
  To: amd-gfx, Alex Deucher, Natalie Vock, Mario Limonciello,
	John Olender, Liu Leo, Arunpravin Paneer Selvam,
	Christian König

On 2026. május 26., kedd 10:10:33 közép-európai nyári idő Christian König 
wrote:
> On 5/25/26 13:33, Timur Kristóf wrote:
> > UVD 4.x and older can only access MSG, FEEDBACK buffers from a
> > specific 256M VRAM segment that the VCPU BO is also located in.
> > We already modify all placements of the given BO to ensure
> > the BO is placed within this segment.
> > 
> > Previously, it always assumed that the VCPU segment is
> > the first 256M of VRAM, even though under some conditions
> > the VCPU BO could be allocated outside this segment,
> > which made UVD non-functional as the BOs were
> > not inside the same segment as the UVD VCPU BO.
> > 
> > Solve that by using the segment where the VCPU BO actually is.
> > 
> > This fixes an issue with UVD failing to initialize on SI/CIK
> > when resizable BAR is enabled and the VCPU BO is allocated
> > in a different segment.
> > 
> > v2:
> > - For other BOs, keep using the same UVD segment as before.
> > 
> > Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3851
> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 33 ++++++++++++++++++-------
> >  1 file changed, 24 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index
> > 1e59ca924abe..480bf88def46 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> > @@ -135,7 +135,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12);
> > 
> >  MODULE_FIRMWARE(FIRMWARE_VEGA20);
> >  
> >  static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
> > 
> > -static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo);
> > +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *abo);
> > 
> >  static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
> >  
> >  					   uint32_t size,
> > 
> > @@ -158,7 +158,7 @@ static int amdgpu_uvd_create_msg_bo_helper(struct
> > amdgpu_device *adev,> 
> >  	amdgpu_bo_kunmap(bo);
> >  	amdgpu_bo_unpin(bo);
> >  	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
> > 
> > -	amdgpu_uvd_force_into_uvd_segment(bo);
> > +	amdgpu_uvd_force_into_vcpu_segment(bo);
> > 
> >  	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
> >  	if (r)
> >  	
> >  		goto err;
> > 
> > @@ -550,6 +550,24 @@ void amdgpu_uvd_free_handles(struct amdgpu_device
> > *adev, struct drm_file *filp)> 
> >  	}
> >  
> >  }
> > 
> > +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *bo)
> > +{
> > +	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
> > +	struct amdgpu_bo *vcpu_bo = adev->uvd.inst[0].vcpu_bo;
> > +	struct amdgpu_res_cursor vcpu_cur;
> > +
> > +	amdgpu_res_first(vcpu_bo->tbo.resource, 0,
> > +			 amdgpu_bo_size(vcpu_bo), &vcpu_cur);
> > +
> > +	bo->placement.num_placement = 1;
> > +	bo->placement.placement = &bo->placements[0];
> > +	bo->placements[0].fpfn = ALIGN_DOWN(vcpu_cur.start, SZ_256M) >>
> > PAGE_SHIFT; +	bo->placements[0].lpfn = bo->placements[0].fpfn + 
(SZ_256M
> > >> PAGE_SHIFT); +	bo->placements[0].mem_type =
> > vcpu_bo->tbo.resource->mem_type;
> > +	if (bo->placements[0].mem_type == TTM_PL_VRAM)
> > +		bo->placements[0].flags |= TTM_PL_FLAG_CONTIGUOUS;
> 
> You need to call ttm_bo_validate() here.

Can you say why?
ttm_bo_validate() is already called by both callers of this function.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)
  2026-05-26 10:13     ` Timur Kristóf
@ 2026-05-26 10:46       ` Christian König
  0 siblings, 0 replies; 9+ messages in thread
From: Christian König @ 2026-05-26 10:46 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx, Alex Deucher, Natalie Vock,
	Mario Limonciello, John Olender, Liu Leo,
	Arunpravin Paneer Selvam

On 5/26/26 12:13, Timur Kristóf wrote:
> On 2026. május 26., kedd 10:10:33 közép-európai nyári idő Christian König 
> wrote:
>> On 5/25/26 13:33, Timur Kristóf wrote:
>>> UVD 4.x and older can only access MSG, FEEDBACK buffers from a
>>> specific 256M VRAM segment that the VCPU BO is also located in.
>>> We already modify all placements of the given BO to ensure
>>> the BO is placed within this segment.
>>>
>>> Previously, it always assumed that the VCPU segment is
>>> the first 256M of VRAM, even though under some conditions
>>> the VCPU BO could be allocated outside this segment,
>>> which made UVD non-functional as the BOs were
>>> not inside the same segment as the UVD VCPU BO.
>>>
>>> Solve that by using the segment where the VCPU BO actually is.
>>>
>>> This fixes an issue with UVD failing to initialize on SI/CIK
>>> when resizable BAR is enabled and the VCPU BO is allocated
>>> in a different segment.
>>>
>>> v2:
>>> - For other BOs, keep using the same UVD segment as before.
>>>
>>> Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3851
>>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>>> ---
>>>
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 33 ++++++++++++++++++-------
>>>  1 file changed, 24 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index
>>> 1e59ca924abe..480bf88def46 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>>> @@ -135,7 +135,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12);
>>>
>>>  MODULE_FIRMWARE(FIRMWARE_VEGA20);
>>>  
>>>  static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
>>>
>>> -static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo);
>>> +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *abo);
>>>
>>>  static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
>>>  
>>>  					   uint32_t size,
>>>
>>> @@ -158,7 +158,7 @@ static int amdgpu_uvd_create_msg_bo_helper(struct
>>> amdgpu_device *adev,> 
>>>  	amdgpu_bo_kunmap(bo);
>>>  	amdgpu_bo_unpin(bo);
>>>  	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
>>>
>>> -	amdgpu_uvd_force_into_uvd_segment(bo);
>>> +	amdgpu_uvd_force_into_vcpu_segment(bo);
>>>
>>>  	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
>>>  	if (r)
>>>  	
>>>  		goto err;
>>>
>>> @@ -550,6 +550,24 @@ void amdgpu_uvd_free_handles(struct amdgpu_device
>>> *adev, struct drm_file *filp)> 
>>>  	}
>>>  
>>>  }
>>>
>>> +static void amdgpu_uvd_force_into_vcpu_segment(struct amdgpu_bo *bo)
>>> +{
>>> +	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>>> +	struct amdgpu_bo *vcpu_bo = adev->uvd.inst[0].vcpu_bo;
>>> +	struct amdgpu_res_cursor vcpu_cur;
>>> +
>>> +	amdgpu_res_first(vcpu_bo->tbo.resource, 0,
>>> +			 amdgpu_bo_size(vcpu_bo), &vcpu_cur);
>>> +
>>> +	bo->placement.num_placement = 1;
>>> +	bo->placement.placement = &bo->placements[0];
>>> +	bo->placements[0].fpfn = ALIGN_DOWN(vcpu_cur.start, SZ_256M) >>
>>> PAGE_SHIFT; +	bo->placements[0].lpfn = bo->placements[0].fpfn + 
> (SZ_256M
>>>>> PAGE_SHIFT); +	bo->placements[0].mem_type =
>>> vcpu_bo->tbo.resource->mem_type;
>>> +	if (bo->placements[0].mem_type == TTM_PL_VRAM)
>>> +		bo->placements[0].flags |= TTM_PL_FLAG_CONTIGUOUS;
>>
>> You need to call ttm_bo_validate() here.
> 
> Can you say why?
> ttm_bo_validate() is already called by both callers of this function.


My bad, I was misreading the code.

In that case Reviewed-by: Christian König <christian.koenig@amd.com>

Thanks,
Christian.

> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-05-26 10:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-25 11:33 [PATCH 0/4] drm/amdgpu/uvd: Fix UVD BO memory placement issues (v2) Timur Kristóf
2026-05-25 11:33 ` [PATCH 1/4] drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions Timur Kristóf
2026-05-25 11:33 ` [PATCH 2/4] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT Timur Kristóf
2026-05-26  8:07   ` Christian König
2026-05-25 11:33 ` [PATCH 3/4] drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older Timur Kristóf
2026-05-25 11:33 ` [PATCH 4/4] drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2) Timur Kristóf
2026-05-26  8:10   ` Christian König
2026-05-26 10:13     ` Timur Kristóf
2026-05-26 10:46       ` Christian König

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.