diff mbox

[10/18] drm/i915/gtt: Lazily allocate page directories for gen7

Message ID 20180608125602.17693-11-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson June 8, 2018, 12:55 p.m. UTC
As we were only supporting aliasing_ppgtt on gen7 for some time, we
saved a few checks by preallocating the page directories on creation.
However, since we need 2MiB of page directories for each ppgtt, to
support arbitrary numbers of user contexts, we need to be more prudent
in our allocations, and defer the page allocation until it is used. We
don't recover unused pages yet as we found that doing so on the fly
(i.e. altering TLB entries) would confuse the GPU.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: Matthew Auld <matthew.william.auld@gmail.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 67 +++++++++++------------------
 1 file changed, 26 insertions(+), 41 deletions(-)

Comments

Matthew Auld June 8, 2018, 2:37 p.m. UTC | #1
On 8 June 2018 at 13:55, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> As we were only supporting aliasing_ppgtt on gen7 for some time, we
> saved a few checks by preallocating the page directories on creation.
> However, since we need 2MiB of page directories for each ppgtt, to
> support arbitrary numbers of user contexts, we need to be more prudent
> in our allocations, and defer the page allocation until it is used. We
> don't recover unused pages yet as we found that doing so on the fly
> (i.e. altering TLB entries) would confuse the GPU.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Cc: Matthew Auld <matthew.william.auld@gmail.com>
> Reviewed-by: Matthew Auld <matthew.william.auld@gmail.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 67 +++++++++++------------------
>  1 file changed, 26 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index d5af099939f6..e611884596a6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -190,11 +190,19 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
>         return 1;
>  }
>
> -static int gen6_ppgtt_bind_vma(struct i915_vma *vma,
> -                              enum i915_cache_level cache_level,
> -                              u32 unused)
> +static int ppgtt_bind_vma(struct i915_vma *vma,
> +                         enum i915_cache_level cache_level,
> +                         u32 unused)
>  {
>         u32 pte_flags;
> +       int err;
> +
> +       if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
> +               err = vma->vm->allocate_va_range(vma->vm,
> +                                                vma->node.start, vma->size);
> +               if (err)
> +                       return err;
> +       }
>
>         /* Currently applicable only to VLV */
>         pte_flags = 0;
> @@ -206,22 +214,6 @@ static int gen6_ppgtt_bind_vma(struct i915_vma *vma,
>         return 0;
>  }
>
> -static int gen8_ppgtt_bind_vma(struct i915_vma *vma,
> -                              enum i915_cache_level cache_level,
> -                              u32 unused)
> -{
> -       int ret;
> -
> -       if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
> -               ret = vma->vm->allocate_va_range(vma->vm,
> -                                                vma->node.start, vma->size);
> -               if (ret)
> -                       return ret;
> -       }
> -
> -       return gen6_ppgtt_bind_vma(vma, cache_level, unused);
> -}
> -
>  static void ppgtt_unbind_vma(struct i915_vma *vma)
>  {
>         vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
> @@ -1622,7 +1614,7 @@ static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
>         ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
>         ppgtt->debug_dump = gen8_dump_ppgtt;
>
> -       ppgtt->vm.vma_ops.bind_vma    = gen8_ppgtt_bind_vma;
> +       ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
>         ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
>         ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
>         ppgtt->vm.vma_ops.clear_pages = clear_pages;
> @@ -1837,7 +1829,8 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
>
>                 num_entries -= end - pte;
>
> -               /* Note that the hw doesn't support removing PDE on the fly
> +               /*
> +                * Note that the hw doesn't support removing PDE on the fly
>                  * (they are cached inside the context with no means to
>                  * invalidate the cache), so we can only reset the PTE
>                  * entries back to scratch.
> @@ -2106,12 +2099,13 @@ static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
>
>         ppgtt->base.vm.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
>
> +       ppgtt->base.vm.allocate_va_range = gen6_alloc_va_range;

Ah, in gen6_alloc_va_range() I think we now need:

unwind_out:
-       gen6_ppgtt_clear_range(vm, from, start);
+       gen6_ppgtt_clear_range(vm, from, start - from);
        return -ENOMEM;
 }

?
Chris Wilson June 8, 2018, 2:43 p.m. UTC | #2
Quoting Matthew Auld (2018-06-08 15:37:43)
> Ah, in gen6_alloc_va_range() I think we now need:
> 
> unwind_out:
> -       gen6_ppgtt_clear_range(vm, from, start);
> +       gen6_ppgtt_clear_range(vm, from, start - from);

You are very right.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d5af099939f6..e611884596a6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -190,11 +190,19 @@  int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
 	return 1;
 }
 
-static int gen6_ppgtt_bind_vma(struct i915_vma *vma,
-			       enum i915_cache_level cache_level,
-			       u32 unused)
+static int ppgtt_bind_vma(struct i915_vma *vma,
+			  enum i915_cache_level cache_level,
+			  u32 unused)
 {
 	u32 pte_flags;
+	int err;
+
+	if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
+		err = vma->vm->allocate_va_range(vma->vm,
+						 vma->node.start, vma->size);
+		if (err)
+			return err;
+	}
 
 	/* Currently applicable only to VLV */
 	pte_flags = 0;
@@ -206,22 +214,6 @@  static int gen6_ppgtt_bind_vma(struct i915_vma *vma,
 	return 0;
 }
 
-static int gen8_ppgtt_bind_vma(struct i915_vma *vma,
-			       enum i915_cache_level cache_level,
-			       u32 unused)
-{
-	int ret;
-
-	if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
-		ret = vma->vm->allocate_va_range(vma->vm,
-						 vma->node.start, vma->size);
-		if (ret)
-			return ret;
-	}
-
-	return gen6_ppgtt_bind_vma(vma, cache_level, unused);
-}
-
 static void ppgtt_unbind_vma(struct i915_vma *vma)
 {
 	vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
@@ -1622,7 +1614,7 @@  static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
 	ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
 	ppgtt->debug_dump = gen8_dump_ppgtt;
 
-	ppgtt->vm.vma_ops.bind_vma    = gen8_ppgtt_bind_vma;
+	ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
 	ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
 	ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
 	ppgtt->vm.vma_ops.clear_pages = clear_pages;
@@ -1837,7 +1829,8 @@  static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
 
 		num_entries -= end - pte;
 
-		/* Note that the hw doesn't support removing PDE on the fly
+		/*
+		 * Note that the hw doesn't support removing PDE on the fly
 		 * (they are cached inside the context with no means to
 		 * invalidate the cache), so we can only reset the PTE
 		 * entries back to scratch.
@@ -2106,12 +2099,13 @@  static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
 
 	ppgtt->base.vm.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
 
+	ppgtt->base.vm.allocate_va_range = gen6_alloc_va_range;
 	ppgtt->base.vm.clear_range = gen6_ppgtt_clear_range;
 	ppgtt->base.vm.insert_entries = gen6_ppgtt_insert_entries;
 	ppgtt->base.vm.cleanup = gen6_ppgtt_cleanup;
 	ppgtt->base.debug_dump = gen6_dump_ppgtt;
 
-	ppgtt->base.vm.vma_ops.bind_vma    = gen6_ppgtt_bind_vma;
+	ppgtt->base.vm.vma_ops.bind_vma    = ppgtt_bind_vma;
 	ppgtt->base.vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
 	ppgtt->base.vm.vma_ops.set_pages   = ppgtt_set_pages;
 	ppgtt->base.vm.vma_ops.clear_pages = clear_pages;
@@ -2136,14 +2130,8 @@  static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
 		goto err_scratch;
 	}
 
-	err = gen6_alloc_va_range(&ppgtt->base.vm, 0, ppgtt->base.vm.total);
-	if (err)
-		goto err_vma;
-
 	return &ppgtt->base;
 
-err_vma:
-	i915_vma_destroy(ppgtt->vma);
 err_scratch:
 	gen6_ppgtt_free_scratch(&ppgtt->base.vm);
 err_free:
@@ -2739,8 +2727,7 @@  static int aliasing_gtt_bind_vma(struct i915_vma *vma,
 	if (flags & I915_VMA_LOCAL_BIND) {
 		struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt;
 
-		if (!(vma->flags & I915_VMA_LOCAL_BIND) &&
-		    appgtt->vm.allocate_va_range) {
+		if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
 			ret = appgtt->vm.allocate_va_range(&appgtt->vm,
 							   vma->node.start,
 							   vma->size);
@@ -2844,17 +2831,15 @@  int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915)
 		goto err_ppgtt;
 	}
 
-	if (ppgtt->vm.allocate_va_range) {
-		/* Note we only pre-allocate as far as the end of the global
-		 * GTT. On 48b / 4-level page-tables, the difference is very,
-		 * very significant! We have to preallocate as GVT/vgpu does
-		 * not like the page directory disappearing.
-		 */
-		err = ppgtt->vm.allocate_va_range(&ppgtt->vm,
-						  0, ggtt->vm.total);
-		if (err)
-			goto err_ppgtt;
-	}
+	/*
+	 * Note we only pre-allocate as far as the end of the global
+	 * GTT. On 48b / 4-level page-tables, the difference is very,
+	 * very significant! We have to preallocate as GVT/vgpu does
+	 * not like the page directory disappearing.
+	 */
+	err = ppgtt->vm.allocate_va_range(&ppgtt->vm, 0, ggtt->vm.total);
+	if (err)
+		goto err_ppgtt;
 
 	i915->mm.aliasing_ppgtt = ppgtt;