Re: [PATCH 23/48] drm/i915: One hopeful eviction on PPGTT alloc

Chris Wilson
2014-03-20T11:12:46Z

On Fri, Dec 06, 2013 at 02:11:56PM -0800, Ben Widawsky wrote:
> The patch before this changed the way in which we allocate space for the
> PPGTT PDEs. It began carving out the PPGTT PDEs (which live in the
> Global GTT) from the GGTT's drm_mm. Prior to that patch, the PDEs were
> hidden from the drm_mm, and therefore could never fail to be allocated.
>
> In unfortunate cases, the drm_mm may be full when we want to allocate
> the space. This can technically occur whenever we try to allocate, which
> happens in two places currently. Practically, it can only really ever
> happen at GPU reset.
>
> Later, when we allocate more PDEs for multiple PPGTTs this will
> potentially even more useful.
>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/i915_gem_gtt.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 4c0b865..0bd0cb9 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -642,6 +642,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
> #define GEN6_PD_SIZE (GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE)
> struct drm_device *dev = ppgtt->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + bool retried = false;
> int i, ret;
>
> /* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
> @@ -649,13 +650,22 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
> * size. We allocate at the top of the GTT to avoid fragmentation.
> */
> BUG_ON(!drm_mm_initialized(&dev_priv->gtt.base.mm));
> +alloc:
> ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm,
> &ppgtt->node, GEN6_PD_SIZE,
> GEN6_PD_ALIGN, 0,
> 0, dev_priv->gtt.base.total,
> DRM_MM_SEARCH_DEFAULT);
> - if (ret)
> - return ret;
> + if (ret == -ENOSPC && !retried) {
> + ret = i915_gem_evict_something(dev, &dev_priv->gtt.base,
> + GEN6_PD_SIZE, GEN6_PD_ALIGN,
> + I915_CACHE_NONE, false, true);
> + if (ret)
> + return ret;
> +
> + retried = true;

retried is redundant; the code will only retry once any way as
i915_gem_evict_something() will fail the second time.
-Chris

--
Chris Wilson, Intel Open Source Technology Centre