[PATCH 4/4] drm/i915: support 1G pages for the 48b PPGTT

Matthew Auld matthew.auld at intel.com
Wed May 16 16:31:07 UTC 2018


Signed-off-by: Matthew Auld <matthew.auld at intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c           |  4 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c           | 12 +++++-
 drivers/gpu/drm/i915/i915_gem_gtt.h           |  4 +-
 drivers/gpu/drm/i915/i915_pci.c               |  6 ++-
 drivers/gpu/drm/i915/selftests/huge_pages.c   | 39 +++++++++++++++----
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  3 +-
 6 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 13e7b9e4a6e6..e52f8d17b60e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -115,10 +115,14 @@ stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len)
 		return "64K";
 	case I915_GTT_PAGE_SIZE_2M:
 		return "2M";
+	case I915_GTT_PAGE_SIZE_1G:
+		return "1G";
 	default:
 		if (!buf)
 			return "M";
 
+		if (page_sizes & I915_GTT_PAGE_SIZE_1G)
+			x += snprintf(buf + x, len - x, "1G, ");
 		if (page_sizes & I915_GTT_PAGE_SIZE_2M)
 			x += snprintf(buf + x, len - x, "2M, ");
 		if (page_sizes & I915_GTT_PAGE_SIZE_64K)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 996ab2ad6c45..468fc96795b7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1090,7 +1090,17 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 		gen8_pte_t *vaddr;
 		u16 index, max;
 
-		if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
+		if (unlikely(vma->page_sizes.sg & I915_GTT_PAGE_SIZE_1G) &&
+		    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_1G) &&
+		    rem >= I915_GTT_PAGE_SIZE_1G && !(idx.pte | idx.pde)) {
+			index = idx.pdpe;
+			max = GEN8_PML4ES_PER_PML4;
+			page_size = I915_GTT_PAGE_SIZE_1G;
+
+			encode |= GEN8_PDPE_PS_1G;
+
+			vaddr = kmap_atomic_px(pdp);
+		} else if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
 		    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) &&
 		    rem >= I915_GTT_PAGE_SIZE_2M && !idx.pte) {
 			index = idx.pde;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index aec4f73574f4..20bb27e8df8c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -45,9 +45,10 @@
 #define I915_GTT_PAGE_SIZE_4K BIT(12)
 #define I915_GTT_PAGE_SIZE_64K BIT(16)
 #define I915_GTT_PAGE_SIZE_2M BIT(21)
+#define I915_GTT_PAGE_SIZE_1G BIT(30)
 
 #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K
-#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M
+#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_1G
 
 #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE
 
@@ -156,6 +157,7 @@ typedef u64 gen8_ppgtt_pml4e_t;
 
 #define GEN8_PDE_IPS_64K BIT(11)
 #define GEN8_PDE_PS_2M   BIT(7)
+#define GEN8_PDPE_PS_1G  BIT(7)
 
 struct sg_table;
 
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 4364922e935d..f8608755bb08 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -391,7 +391,8 @@ static const struct intel_device_info intel_haswell_gt3_info = {
 	GEN(8), \
 	BDW_COLORS, \
 	.page_sizes = I915_GTT_PAGE_SIZE_4K | \
-		      I915_GTT_PAGE_SIZE_2M, \
+		      I915_GTT_PAGE_SIZE_2M | \
+		      I915_GTT_PAGE_SIZE_1G, \
 	.has_logical_ring_contexts = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_64bit_reloc = 1, \
@@ -453,7 +454,8 @@ static const struct intel_device_info intel_cherryview_info = {
 #define GEN9_DEFAULT_PAGE_SIZES \
 	.page_sizes = I915_GTT_PAGE_SIZE_4K | \
 		      I915_GTT_PAGE_SIZE_64K | \
-		      I915_GTT_PAGE_SIZE_2M
+		      I915_GTT_PAGE_SIZE_2M | \
+		      I915_GTT_PAGE_SIZE_1G
 
 #define GEN9_FEATURES \
 	GEN8_FEATURES, \
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index 91c72911be3c..2c83c4703949 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -29,7 +29,10 @@
 #include "mock_drm.h"
 #include "i915_random.h"
 
+static struct page *gigantic_page;
+
 static const unsigned int page_sizes[] = {
+	I915_GTT_PAGE_SIZE_1G,
 	I915_GTT_PAGE_SIZE_2M,
 	I915_GTT_PAGE_SIZE_64K,
 	I915_GTT_PAGE_SIZE_4K,
@@ -55,8 +58,12 @@ static void huge_pages_free_pages(struct sg_table *st)
 	struct scatterlist *sg;
 
 	for (sg = st->sgl; sg; sg = __sg_next(sg)) {
-		if (sg_page(sg))
-			__free_pages(sg_page(sg), get_order(sg->length));
+		if (sg_page(sg)) {
+			unsigned int order = get_order(sg->length);
+
+			if (order < MAX_ORDER)
+				__free_pages(sg_page(sg), order);
+		}
 	}
 
 	sg_free_table(st);
@@ -97,10 +104,11 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 		int order = get_order(page_size);
 
 		do {
-			struct page *page;
+			struct page *page = gigantic_page;
+
+			if (order < MAX_ORDER)
+				page = alloc_pages(GFP | __GFP_ZERO, order);
 
-			GEM_BUG_ON(order >= MAX_ORDER);
-			page = alloc_pages(GFP | __GFP_ZERO, order);
 			if (!page)
 				goto err;
 
@@ -1072,6 +1080,9 @@ static int __igt_write_huge(struct i915_gem_context *ctx,
 		goto out_vma_close;
 	}
 
+	if (vma->page_sizes.gtt == I915_GTT_PAGE_SIZE_1G)
+		pr_info("long live 1g pages!\n");
+
 	err = igt_check_page_sizes(vma);
 	if (err)
 		goto out_vma_unpin;
@@ -1262,6 +1273,7 @@ static int igt_ppgtt_exhaust_huge(void *arg)
 			}
 
 			i915_gem_object_unpin_pages(obj);
+			__i915_gem_object_put_pages(obj, I915_MM_NORMAL);
 			i915_gem_object_put(obj);
 		}
 	}
@@ -1728,16 +1740,16 @@ int i915_gem_huge_page_mock_selftests(void)
 int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv)
 {
 	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_ppgtt_exhaust_huge),
 		SUBTEST(igt_shrink_thp),
 		SUBTEST(igt_ppgtt_pin_update),
 		SUBTEST(igt_tmpfs_fallback),
-		SUBTEST(igt_ppgtt_exhaust_huge),
 		SUBTEST(igt_ppgtt_gemfs_huge),
 		SUBTEST(igt_ppgtt_internal_huge),
 	};
 	struct drm_file *file;
 	struct i915_gem_context *ctx;
-	int err;
+	int err = 0;
 
 	if (!USES_PPGTT(dev_priv)) {
 		pr_info("PPGTT not supported, skipping live-selftests\n");
@@ -1760,8 +1772,21 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv)
 	if (ctx->ppgtt)
 		ctx->ppgtt->base.scrub_64K = true;
 
+	if (HAS_PAGE_SIZES(dev_priv, I915_GTT_PAGE_SIZE_1G)) {
+		gigantic_page = find_alloc_contig_pages(I915_GTT_PAGE_SIZE_1G >> PAGE_SHIFT,
+							GFP_KERNEL | __GFP_NOWARN,
+							0, 0);
+		if (!gigantic_page) {
+			pr_info("too big\n");
+			goto out_unlock;
+		}
+	}
+
 	err = i915_subtests(tests, ctx);
 
+	if (gigantic_page)
+		free_contig_pages(gigantic_page, I915_GTT_PAGE_SIZE_1G >> PAGE_SHIFT);
+
 out_unlock:
 	intel_runtime_pm_put(dev_priv);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 94baedfa0f74..3c90c74ab36a 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -180,7 +180,8 @@ struct drm_i915_private *mock_gem_device(void)
 	mkwrite_device_info(i915)->page_sizes =
 		I915_GTT_PAGE_SIZE_4K |
 		I915_GTT_PAGE_SIZE_64K |
-		I915_GTT_PAGE_SIZE_2M;
+		I915_GTT_PAGE_SIZE_2M |
+		I915_GTT_PAGE_SIZE_1G;
 
 	mock_uncore_init(i915);
 	i915_gem_init__mm(i915);
-- 
2.17.0



More information about the Intel-gfx-trybot mailing list