On Fri, Jul 10, 2026 at 5:54 AM Zhu Lingshan <[email protected]> wrote:
>
> amdgpu_bo_create_reserved() only allocates a new BO when
> *bo_ptr (struct amdgpu_bo **bo_ptr as input parameter) is
> NULL, it simply skips creation when *bo_ptr is non-NULL.
> But it unconditionally reserves, pins, gart allocates
> and maps the BO afterwards.
>
> When the same non-NULL BO pointer is passed in again,
> for example firmware buffers that live in adev and are
> re-loaded on every resume / cp_resume / start
> under AMDGPU_FW_LOAD_DIRECT, amdgpu_bo_pin() just increases
> pin_count unconditionally, however the matching teardown only unpins
> once, so pin_count never drops to zero, so TTM is not able
> to move, swap or evict a BO, causing BO leaks.
>
> This commit fixes this issue by only pinning the bo
> once at creation, and repeated calls no longer
> take additional pin references.
>
> Signed-off-by: Zhu Lingshan <[email protected]>

Reviewed-by: Alex Deucher <[email protected]>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 4dd7c712b8c3..7ac3b8fd963a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -276,10 +276,12 @@ int amdgpu_bo_create_reserved(struct amdgpu_device 
> *adev,
>                 goto error_free;
>         }
>
> -       r = amdgpu_bo_pin(*bo_ptr, domain);
> -       if (r) {
> -               dev_err(adev->dev, "(%d) kernel bo pin failed\n", r);
> -               goto error_unreserve;
> +       if (free) {
> +               r = amdgpu_bo_pin(*bo_ptr, domain);
> +               if (r) {
> +                       dev_err(adev->dev, "(%d) kernel bo pin failed\n", r);
> +                       goto error_unreserve;
> +               }
>         }
>
>         r = amdgpu_ttm_alloc_gart(&(*bo_ptr)->tbo);
> @@ -302,7 +304,8 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
>         return 0;
>
>  error_unpin:
> -       amdgpu_bo_unpin(*bo_ptr);
> +       if (free)
> +               amdgpu_bo_unpin(*bo_ptr);
>  error_unreserve:
>         amdgpu_bo_unreserve(*bo_ptr);
>
> --
> 2.55.0
>

Reply via email to