[Intel-gfx] [PATCH] drm/i915/ttm: Fix incorrect assumptions about ttm_bo_validate() semantics

Matthew Auld matthew.william.auld at gmail.com
Fri Jun 18 10:53:55 UTC 2021


On Fri, 18 Jun 2021 at 09:31, Thomas Hellström
<thomas.hellstrom at linux.intel.com> wrote:
>
> We have assumed that if the current placement was not the requested
> placement, but instead one of the busy placements, a TTM move would have
> been triggered. That is not the case.
>
> So when we initially place LMEM objects in "Limbo", (that is system
> placement without any pages allocated), to be able to defer clearing
> objects until first get_pages(), the first get_pages() would happily keep
> objects in system memory if that is one of the allowed placements. And
> since we don't yet support i915 GEM system memory from TTM, everything
> breaks apart.
>
> So make sure we try the requested placement first, if no eviction is
> needed. If that fails, retry with all allowed placements also allowing
> evictions. Also make sure we handle TTM failure codes correctly.
>
> Also temporarily (until we support i915 GEM system on TTM), restrict
> allowed placements to the requested placement to avoid things falling
> apart should LMEM be full.
>
> Fixes: 38f28c0695c0 ("drm/i915/ttm: Calculate the object placement at get_pages time)
> Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 61 +++++++++++++++++++++++--
>  1 file changed, 58 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index df46535cca47..4bb0440f693c 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -64,6 +64,30 @@ static struct ttm_placement i915_sys_placement = {
>         .busy_placement = &sys_placement_flags,
>  };
>
> +static int i915_ttm_err_to_gem(int err)
> +{
> +       /* Fastpath */
> +       if (likely(!err))
> +               return 0;
> +
> +       switch (err) {
> +       case -EBUSY:
> +               /*
> +                * TTM likes to convert -EDEADLK to -EBUSY, and wants us to
> +                * restart the operation, since we don't record the contending
> +                * lock. We use -EAGAIN to restart.
> +                */
> +               return -EAGAIN;
> +       case -ENOSPC:
> +               /* Memory type / region is full, and we can't evict. */
> +               return -ENXIO;

ttm system will return -ENOMEM right?

Reviewed-by: Matthew Auld <matthew.auld at intel.com>

> +       default:
> +               break;
> +       }
> +
> +       return err;
> +}
> +
>  static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj);
>
>  static enum ttm_caching
> @@ -522,15 +546,46 @@ static int i915_ttm_get_pages(struct drm_i915_gem_object *obj)
>         struct sg_table *st;
>         struct ttm_place requested, busy[I915_TTM_MAX_PLACEMENTS];
>         struct ttm_placement placement;
> +       int real_num_busy;
>         int ret;
>
>         GEM_BUG_ON(obj->mm.n_placements > I915_TTM_MAX_PLACEMENTS);
>
>         /* Move to the requested placement. */
>         i915_ttm_placement_from_obj(obj, &requested, busy, &placement);
> +
> +       /*
> +        * For now we support LMEM only with TTM.
> +        * TODO: Remove with system support
> +        */
> +       GEM_BUG_ON(requested.mem_type < I915_PL_LMEM0 ||
> +                  busy[0].mem_type < I915_PL_LMEM0);
> +
> +       /* First try only the requested placement. No eviction. */
> +       real_num_busy = fetch_and_zero(&placement.num_busy_placement);
>         ret = ttm_bo_validate(bo, &placement, &ctx);
> -       if (ret)
> -               return ret == -ENOSPC ? -ENXIO : ret;
> +       if (ret) {
> +               ret = i915_ttm_err_to_gem(ret);
> +               /*
> +                * Anything that wants to restart the operation gets to
> +                * do that.
> +                */
> +               if (ret == -EDEADLK || ret == -EINTR || ret == -ERESTARTSYS ||
> +                   ret == -EAGAIN)
> +                       return ret;
> +
> +               /* TODO: Remove this when we support system as TTM. */
> +               real_num_busy = 1;
> +
> +               /*
> +                * If the initial attempt fails, allow all accepted placements,
> +                * evicting if necessary.
> +                */
> +               placement.num_busy_placement = real_num_busy;
> +               ret = ttm_bo_validate(bo, &placement, &ctx);
> +               if (ret)
> +                       return i915_ttm_err_to_gem(ret);
> +       }
>
>         /* Object either has a page vector or is an iomem object */
>         st = bo->ttm ? i915_ttm_tt_get_st(bo->ttm) : obj->ttm.cached_io_st;
> @@ -741,5 +796,5 @@ int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
>                 obj->ttm.created = true;
>
>         /* i915 wants -ENXIO when out of memory region space. */
> -       return (ret == -ENOSPC) ? -ENXIO : ret;
> +       return i915_ttm_err_to_gem(ret);
>  }
> --
> 2.31.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list