> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf
> Of Christian König
> Sent: Thursday, September 01, 2016 10:16 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH 2/2] drm/amdgpu: prevent command submission failures
> under memory pressure
> 
> From: Christian König <christian.koe...@amd.com>
> 
> As last resort try to evict BOs from the current working set into other
> memory domains. This effectively prevents command submission failures
> when
> VM page tables have been swapped out.
> 
> Signed-off-by: Christian König <christian.koe...@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h    |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 65
> +++++++++++++++++++++++++++++++++-
>  2 files changed, 65 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 03ba035..ee2eeaa 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1225,6 +1225,7 @@ struct amdgpu_cs_parser {
>       struct fence                    *fence;
>       uint64_t                        bytes_moved_threshold;
>       uint64_t                        bytes_moved;
> +     struct amdgpu_bo_list_entry     *evictable;
> 
>       /* user fence */
>       struct amdgpu_bo_list_entry     uf_entry;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index 23964b8..09adc75 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -378,6 +378,60 @@ retry:
>       }
> 
>       return r;
> +
> +     return -ENOMEM;
> +}

Unreachable code.  Other than that looks good.  With that fixed:
Reviewed-by: Alex Deucher <alexander.deuc...@amd.com>

Alex

> +
> +/* Last resort try to evict something from the current working set */
> +static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
> +                             struct amdgpu_bo_list_entry *lobj)
> +{
> +     uint32_t domain = lobj->robj->allowed_domains;
> +     int r;
> +
> +     if (!p->evictable)
> +             return false;
> +
> +     for (;&p->evictable->tv.head != &p->validated;
> +          p->evictable = list_prev_entry(p->evictable, tv.head)) {
> +
> +             struct amdgpu_bo_list_entry *candidate = p->evictable;
> +             struct amdgpu_bo *bo = candidate->robj;
> +             u64 initial_bytes_moved;
> +             uint32_t other;
> +
> +             /* If we reached our current BO we can forget it */
> +             if (candidate == lobj)
> +                     break;
> +
> +             other = amdgpu_mem_type_to_domain(bo-
> >tbo.mem.mem_type);
> +
> +             /* Check if this BO is in one of the domains we need space
> for */
> +             if (!(other & domain))
> +                     continue;
> +
> +             /* Check if we can move this BO somewhere else */
> +             other = bo->allowed_domains & ~domain;
> +             if (!other)
> +                     continue;
> +
> +             /* Good we can try to move this BO somewhere else */
> +             amdgpu_ttm_placement_from_domain(bo, other);
> +             initial_bytes_moved = atomic64_read(&bo->adev-
> >num_bytes_moved);
> +             r = ttm_bo_validate(&bo->tbo, &bo->placement, true,
> false);
> +             p->bytes_moved += atomic64_read(&bo->adev-
> >num_bytes_moved) -
> +                     initial_bytes_moved;
> +
> +             if (unlikely(r))
> +                     break;
> +
> +             p->evictable = list_prev_entry(p->evictable, tv.head);
> +             list_move(&candidate->tv.head, &p->validated);
> +
> +             return true;
> +     }
> +
> +     return false;
>  }
> 
>  int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
> @@ -404,9 +458,15 @@ int amdgpu_cs_list_validate(struct
> amdgpu_cs_parser *p,
>                       binding_userptr = true;
>               }
> 
> -             r = amdgpu_cs_bo_validate(p, bo);
> +             if (p->evictable == lobj)
> +                     p->evictable = NULL;
> +
> +             do {
> +                     r = amdgpu_cs_bo_validate(p, bo);
> +             } while (r == -ENOMEM && amdgpu_cs_try_evict(p, lobj));
>               if (r)
>                       return r;
> +
>               if (bo->shadow) {
>                       r = amdgpu_cs_bo_validate(p, bo);
>                       if (r)
> @@ -534,6 +594,9 @@ static int amdgpu_cs_parser_bos(struct
> amdgpu_cs_parser *p,
> 
>       p->bytes_moved_threshold =
> amdgpu_cs_get_threshold_for_moves(p->adev);
>       p->bytes_moved = 0;
> +     p->evictable = list_last_entry(&p->validated,
> +                                    struct amdgpu_bo_list_entry,
> +                                    tv.head);
> 
>       r = amdgpu_cs_list_validate(p, &duplicates);
>       if (r) {
> --
> 2.5.0
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to