Does this patch fix the problem? Alex On Wed, Dec 7, 2022 at 2:27 AM Zhang, Jesse(Jie) <Jesse.Zhang@xxxxxxx> wrote: > > [AMD Official Use Only - General] > > > drm/amdgpu: try allowed domain when pin framebuffer failed. > > > > [WHY&HOW] > > > > in some scenarios, the allocate memory often failed. such as do hot plug or play games. > > so we can try allowed domain, if the preferred domain cannot allocate memory. > > > > Signed-off-by: jie1zhan jesse.zhang@xxxxxxx > > Change-Id: I4b62e2ff072d02c515f901000a5789339d481273 > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > > index 1ae0c8723348..05fcaf7f9d92 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > > @@ -39,6 +39,7 @@ > > #include "amdgpu.h" > > #include "amdgpu_trace.h" > > #include "amdgpu_amdkfd.h" > > +#include "amdgpu_display.h" > > > > /** > > * DOC: amdgpu_object > > @@ -942,8 +943,14 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, > > bo->placements[i].lpfn = lpfn; > > } > > > > + retry: > > r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); > > if (unlikely(r)) { > > + //try allowed domain when pin failed. just a workaround. > > + if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { > > + amdgpu_bo_placement_from_domain(bo, bo->allowed_domains); > > + goto retry; > > + } > > dev_err(adev->dev, "%p pin failed\n", bo); > > goto error; > > }
From 2fb9f97fe2821554a2e387ee95942302fb1003c6 Mon Sep 17 00:00:00 2001 From: Alex Deucher <alexander.deucher@xxxxxxx> Date: Mon, 9 May 2022 12:16:31 -0400 Subject: [PATCH] drm/amdgpu: make display pinning more flexible We originally used a static threshold for whether to use vram or system memory for display pinning due to hardware requirements on Carrizo around placement of buffers which mostly boiled down to not mixing domains. Newer asics do not have these requirements so we should be able to be more flexible with where buffers end up. Add a new parameter to amdgpu_bo_get_preferred_domain() and check the size of the allocation against what is already pinned to determine which domain to use for pinning. This should avoid running out of room in one domain or the other due to using a static threshold. Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 18 +++++++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 62e98f1ad770..8ecd4f25c6f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -918,7 +918,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, args->size = (u64)args->pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); domain = amdgpu_bo_get_preferred_domain(adev, - amdgpu_display_supported_domains(adev, flags)); + amdgpu_display_supported_domains(adev, flags), + args->size); r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags, ttm_bo_type_device, NULL, &gobj); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 919bbea2e3ac..ec0abc4e730c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -921,7 +921,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, /* This assumes only APU display buffers are pinned with (VRAM|GTT). * See function amdgpu_display_supported_domains() */ - domain = amdgpu_bo_get_preferred_domain(adev, domain); + domain = amdgpu_bo_get_preferred_domain(adev, domain, amdgpu_bo_size(bo)); if (bo->tbo.base.import_attach) dma_buf_pin(bo->tbo.base.import_attach); @@ -1504,12 +1504,24 @@ u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo) * Which of the allowed domains is preferred for allocating the BO. */ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev, - uint32_t domain) + uint32_t domain, u64 size) { if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) { + u64 usable_vram_size = (adev->gmc.real_vram_size - + atomic64_read(&adev->vram_pin_size) - + AMDGPU_VM_RESERVED_VRAM) * 3 / 4; + domain = AMDGPU_GEM_DOMAIN_VRAM; - if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD) + /* Use a fixed threshold on CZ due to hw restrictions + * (no mixing of system and vram for display), for everything + * else, use a dynamic calculation. + */ + if ((adev->asic_type == CHIP_CARRIZO) || (adev->asic_type == CHIP_STONEY)) { + if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD) + domain = AMDGPU_GEM_DOMAIN_GTT; + } else if (usable_vram_size <= size) { domain = AMDGPU_GEM_DOMAIN_GTT; + } } return domain; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 147b79c10cbb..197accb2f402 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -331,7 +331,7 @@ void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo); int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence); uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev, - uint32_t domain); + uint32_t domain, u64 size); /* * sub allocation diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index b5f3bba851db..247a5714db4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c @@ -513,7 +513,7 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm, bp.size = amdgpu_vm_pt_size(adev, level); bp.byte_align = AMDGPU_GPU_PAGE_SIZE; bp.domain = AMDGPU_GEM_DOMAIN_VRAM; - bp.domain = amdgpu_bo_get_preferred_domain(adev, bp.domain); + bp.domain = amdgpu_bo_get_preferred_domain(adev, bp.domain, bp.size); bp.flags = AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_CPU_GTT_USWC; -- 2.38.1