diff mbox

[12/19] drm/i915: support 64K pages for the 48b PPGTT

Message ID 20170621203345.26320-13-matthew.auld@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matthew Auld June 21, 2017, 8:33 p.m. UTC
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
 2 files changed, 27 insertions(+)

Comments

Chris Wilson June 21, 2017, 9:55 p.m. UTC | #1
Quoting Matthew Auld (2017-06-21 21:33:38)
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 26 ++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 03c35097ef39..9b89ec10f333 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -937,6 +937,7 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>                 struct i915_page_table *pt = pd->page_table[idx.pde];
>                 dma_addr_t rem = iter->max - iter->dma;
>                 unsigned int page_size;
> +               bool maybe_64K = false;
>                 gen8_pte_t encode = pte_encode;
>                 gen8_pte_t *vaddr;
>                 u16 index, max;
> @@ -962,9 +963,17 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>                         index = idx.pte;
>                         max = GEN8_PTES;
>                         page_size = I915_GTT_PAGE_SIZE;
> +
> +                       if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K && !idx.pte)
> +                               maybe_64K = true;
>                 }
>  
>                 do {
> +                       if (maybe_64K && (index % 16 == 0) &&
> +                           (!IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) ||
> +                            rem < I915_GTT_PAGE_SIZE_64K))
> +                               maybe_64K = false;
> +
>                         vaddr[index++] = encode | iter->dma;
>  
>                         start += page_size;
> @@ -986,6 +995,23 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>  
>                 kunmap_atomic(vaddr);
>  
> +
> +               /* Is it safe to mark the 2M block as 64K? -- Either we have
> +                * filled whole page-table with 64K entries, or filled part of
> +                * it and have reached the end of the sg table and we have
> +                * enough padding.
> +                */
> +               if (maybe_64K) {
> +                       if (index == max ||
> +                           (!iter->sg && IS_ALIGNED(vma->node.start +
> +                                                    vma->node.size,
> +                                                    I915_GTT_PAGE_SIZE_2M))) {
> +                               vaddr = kmap_atomic_px(pd);
> +                               vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
> +                               kunmap_atomic(vaddr);
> +                       }

Hmm. I think you know this at the start. It's a bit hard to see from
this diff why not.
-Chris
Matthew Auld June 22, 2017, 11:27 a.m. UTC | #2
On 21 June 2017 at 22:55, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> Quoting Matthew Auld (2017-06-21 21:33:38)
>> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
>> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_gem_gtt.c | 26 ++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
>>  2 files changed, 27 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> index 03c35097ef39..9b89ec10f333 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> @@ -937,6 +937,7 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>>                 struct i915_page_table *pt = pd->page_table[idx.pde];
>>                 dma_addr_t rem = iter->max - iter->dma;
>>                 unsigned int page_size;
>> +               bool maybe_64K = false;
>>                 gen8_pte_t encode = pte_encode;
>>                 gen8_pte_t *vaddr;
>>                 u16 index, max;
>> @@ -962,9 +963,17 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>>                         index = idx.pte;
>>                         max = GEN8_PTES;
>>                         page_size = I915_GTT_PAGE_SIZE;
>> +
>> +                       if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K && !idx.pte)
>> +                               maybe_64K = true;
>>                 }
>>
>>                 do {
>> +                       if (maybe_64K && (index % 16 == 0) &&
>> +                           (!IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) ||
>> +                            rem < I915_GTT_PAGE_SIZE_64K))
>> +                               maybe_64K = false;
>> +
>>                         vaddr[index++] = encode | iter->dma;
>>
>>                         start += page_size;
>> @@ -986,6 +995,23 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
>>
>>                 kunmap_atomic(vaddr);
>>
>> +
>> +               /* Is it safe to mark the 2M block as 64K? -- Either we have
>> +                * filled whole page-table with 64K entries, or filled part of
>> +                * it and have reached the end of the sg table and we have
>> +                * enough padding.
>> +                */
>> +               if (maybe_64K) {
>> +                       if (index == max ||
>> +                           (!iter->sg && IS_ALIGNED(vma->node.start +
>> +                                                    vma->node.size,
>> +                                                    I915_GTT_PAGE_SIZE_2M))) {
>> +                               vaddr = kmap_atomic_px(pd);
>> +                               vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
>> +                               kunmap_atomic(vaddr);
>> +                       }
>
> Hmm. I think you know this at the start. It's a bit hard to see from
> this diff why not.

Not sure I follow, what do we know from the start?

> -Chris
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 03c35097ef39..9b89ec10f333 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -937,6 +937,7 @@  static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 		struct i915_page_table *pt = pd->page_table[idx.pde];
 		dma_addr_t rem = iter->max - iter->dma;
 		unsigned int page_size;
+		bool maybe_64K = false;
 		gen8_pte_t encode = pte_encode;
 		gen8_pte_t *vaddr;
 		u16 index, max;
@@ -962,9 +963,17 @@  static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 			index = idx.pte;
 			max = GEN8_PTES;
 			page_size = I915_GTT_PAGE_SIZE;
+
+			if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K && !idx.pte)
+				maybe_64K = true;
 		}
 
 		do {
+			if (maybe_64K && (index % 16 == 0) &&
+			    (!IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) ||
+			     rem < I915_GTT_PAGE_SIZE_64K))
+				maybe_64K = false;
+
 			vaddr[index++] = encode | iter->dma;
 
 			start += page_size;
@@ -986,6 +995,23 @@  static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 
 		kunmap_atomic(vaddr);
 
+
+		/* Is it safe to mark the 2M block as 64K? -- Either we have
+		 * filled whole page-table with 64K entries, or filled part of
+		 * it and have reached the end of the sg table and we have
+		 * enough padding.
+		 */
+		if (maybe_64K) {
+			if (index == max ||
+			    (!iter->sg && IS_ALIGNED(vma->node.start +
+						     vma->node.size,
+						     I915_GTT_PAGE_SIZE_2M))) {
+				vaddr = kmap_atomic_px(pd);
+				vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
+				kunmap_atomic(vaddr);
+			}
+		}
+
 	} while (iter->sg);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e9ec75b92f85..41df07e5e37a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -149,6 +149,7 @@  typedef u64 gen8_ppgtt_pml4e_t;
 #define GEN8_PPAT_ELLC_OVERRIDE		(0<<2)
 #define GEN8_PPAT(i, x)			((u64)(x) << ((i) * 8))
 
+#define GEN8_PDE_IPS_64K BIT(11)
 #define GEN8_PDE_PS_2M   BIT(7)
 
 #define GEN8_PDPE_PS_1G  BIT(7)