[PATCH 57/78] ggtt-fill

Chris Wilson chris at chris-wilson.co.uk
Sun Jan 1 15:11:44 UTC 2017


---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 111 +++++++++++++++++++-------
 1 file changed, 81 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 5d0e6f60bea7..01640b558a0a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -94,35 +94,25 @@ static struct i915_vma *vma_lookup(struct drm_i915_gem_object *obj,
 	return i915_gem_obj_lookup_or_create_vma(obj, vm, NULL);
 }
 
-static int igt_ppgtt_fill(void *arg)
+static int fill_hole(struct drm_i915_private *i915,
+		     struct i915_address_space *vm,
+		     u64 hole_start, u64 hole_end)
 {
-	struct drm_i915_private *dev_priv = arg;
 	unsigned long npages, max_pages = 1 << 20, prime;
+	u64 hole_size = hole_end - hole_start;
 	struct drm_i915_gem_object *obj, *on;
-	struct i915_hw_ppgtt *ppgtt;
 	struct i915_vma *vma;
 	LIST_HEAD(objects);
-	int err = 0;
-
-	if (!USES_FULL_PPGTT(dev_priv))
-		return 0;
-
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	ppgtt = i915_ppgtt_create(dev_priv, NULL, "mock");
-	if (IS_ERR(ppgtt)) {
-		err = PTR_ERR(ppgtt);
-		goto err_unlock;
-	}
-	GEM_BUG_ON(ppgtt->base.total & ~PAGE_MASK);
+	int err;
 
-	max_pages = min_t(u64, max_pages, ppgtt->base.total/2 >> PAGE_SHIFT);
+	max_pages = min_t(u64, max_pages, hole_size/2 >> PAGE_SHIFT);
 
 	for_each_prime_number_from(prime, 2, 13) {
 		for (npages = 1; npages <= max_pages; npages *= prime) {
 			u64 flags;
 
 			GEM_BUG_ON(!npages);
-			obj = huge_gem_object(dev_priv,
+			obj = huge_gem_object(i915,
 					      PAGE_SIZE,
 					      npages << PAGE_SHIFT);
 			if (IS_ERR(obj))
@@ -131,9 +121,9 @@ static int igt_ppgtt_fill(void *arg)
 			list_add(&obj->batch_pool_link, &objects);
 
 			/* Fill the GTT top down - hope we don't overstep the end */
-			flags = ppgtt->base.total | PIN_OFFSET_FIXED | PIN_USER;
+			flags = hole_end | PIN_OFFSET_FIXED | PIN_USER;
 			list_for_each_entry(obj, &objects, batch_pool_link) {
-				vma = vma_lookup(obj, &ppgtt->base);
+				vma = vma_lookup(obj, vm);
 				if (IS_ERR(vma))
 					continue;
 
@@ -147,9 +137,9 @@ static int igt_ppgtt_fill(void *arg)
 				i915_vma_unpin(vma);
 			}
 
-			flags = ppgtt->base.total | PIN_OFFSET_FIXED | PIN_USER;
+			flags = hole_end | PIN_OFFSET_FIXED | PIN_USER;
 			list_for_each_entry(obj, &objects, batch_pool_link) {
-				vma = vma_lookup(obj, &ppgtt->base);
+				vma = vma_lookup(obj, vm);
 				if (IS_ERR(vma))
 					continue;
 
@@ -173,9 +163,9 @@ static int igt_ppgtt_fill(void *arg)
 			}
 
 			/* And again from the bottom */
-			flags = PIN_OFFSET_FIXED | PIN_USER;
+			flags = hole_start | PIN_OFFSET_FIXED | PIN_USER;
 			list_for_each_entry(obj, &objects, batch_pool_link) {
-				vma = vma_lookup(obj, &ppgtt->base);
+				vma = vma_lookup(obj, vm);
 				if (IS_ERR(vma))
 					continue;
 
@@ -189,9 +179,9 @@ static int igt_ppgtt_fill(void *arg)
 				flags += obj->base.size;
 			}
 
-			flags = PIN_OFFSET_FIXED | PIN_USER;
+			flags = hole_start | PIN_OFFSET_FIXED | PIN_USER;
 			list_for_each_entry(obj, &objects, batch_pool_link) {
-				vma = vma_lookup(obj, &ppgtt->base);
+				vma = vma_lookup(obj, vm);
 				if (IS_ERR(vma))
 					continue;
 
@@ -218,28 +208,88 @@ static int igt_ppgtt_fill(void *arg)
 
 		list_for_each_entry_safe(obj, on, &objects, batch_pool_link) {
 			list_del(&obj->batch_pool_link);
-			vma = vma_lookup(obj, &ppgtt->base);
-			if (!IS_ERR(vma))
+			vma = vma_lookup(obj, vm);
+			if (!IS_ERR(vma) && !i915_vma_is_ggtt(vma))
 				i915_vma_close(vma);
 
 			i915_gem_object_put(obj);
 		}
 	}
-err:
 
+	return 0;
+
+err:
 	list_for_each_entry_safe(obj, on, &objects, batch_pool_link) {
 		list_del(&obj->batch_pool_link);
-		vma = vma_lookup(obj, &ppgtt->base);
-		if (!IS_ERR(vma))
+		vma = vma_lookup(obj, vm);
+		if (!IS_ERR(vma) && !i915_vma_is_ggtt(vma))
 			i915_vma_close(vma);
 
 		i915_gem_object_put(obj);
 	}
+	return err;
+}
+
+static int igt_ppgtt_fill(void *arg)
+{
+	struct drm_i915_private *dev_priv = arg;
+	struct i915_hw_ppgtt *ppgtt;
+	int err;
+
+	if (!USES_FULL_PPGTT(dev_priv))
+		return 0;
+
+	mutex_lock(&dev_priv->drm.struct_mutex);
+	ppgtt = i915_ppgtt_create(dev_priv, NULL, "mock");
+	if (IS_ERR(ppgtt)) {
+		err = PTR_ERR(ppgtt);
+		goto err_unlock;
+	}
+	GEM_BUG_ON(ppgtt->base.total & ~PAGE_MASK);
+
+	err = fill_hole(dev_priv, &ppgtt->base, 0, ppgtt->base.total);
 
 	i915_ppgtt_close(&ppgtt->base);
 	i915_ppgtt_put(ppgtt);
 err_unlock:
 	mutex_unlock(&dev_priv->drm.struct_mutex);
+
+	return err;
+}
+
+static int igt_ggtt_fill(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct i915_ggtt *ggtt = &i915->ggtt;
+	u64 hole_start = U64_MAX, hole_end = 0, hole_size = 0;
+	u64 this_start, this_end;
+	struct drm_mm_node *node;
+	int err;
+
+	GEM_BUG_ON(ggtt->base.total & ~PAGE_MASK);
+
+	mutex_lock(&i915->drm.struct_mutex);
+	drm_mm_for_each_hole(node, &ggtt->base.mm, this_start, this_end) {
+		u64 this_size;
+
+		if (ggtt->base.mm.color_adjust)
+			ggtt->base. mm.color_adjust(node, 0,
+						    &this_start, &this_end);
+
+		this_size = this_end - this_start;
+		if (this_size > hole_size) {
+			hole_size = this_size;
+			hole_start = this_start;
+			hole_end = this_end;
+		}
+	}
+	pr_info("Found GGTT hole [%llx, %llx], size %llx\n",
+		hole_start, hole_end, hole_size);
+	GEM_BUG_ON(hole_start >= hole_end);
+
+	err = fill_hole(i915, &ggtt->base, hole_start, hole_end);
+	mutex_unlock(&i915->drm.struct_mutex);
+
 	return err;
 }
 
@@ -248,6 +298,7 @@ int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_ppgtt_alloc),
 		SUBTEST(igt_ppgtt_fill),
+		SUBTEST(igt_ggtt_fill),
 	};
 
 	return i915_subtests(tests, i915);
-- 
2.11.0



More information about the Intel-gfx-trybot mailing list