[PATCH] drm/i915/selftests/blt: try to be more resilient against the GGTT

Matthew Auld matthew.auld at intel.com
Fri Nov 1 13:24:42 UTC 2019


For a tiny shared address space, where parts of it might already be
reserved, we should expect to hit the occasional -ENOSPC.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112176
Signed-off-by: Matthew Auld <matthew.auld at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
---
 .../i915/gem/selftests/i915_gem_object_blt.c  | 102 +++++++++++-------
 1 file changed, 66 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c
index e8132aca0bb6..3dd4d69f9684 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c
@@ -201,6 +201,7 @@ static int igt_fill_blt_thread(void *arg)
 	struct drm_file *file;
 	unsigned int prio;
 	IGT_TIMEOUT(end);
+	u64 total;
 	int err;
 
 	file = mock_file(i915);
@@ -219,27 +220,31 @@ static int igt_fill_blt_thread(void *arg)
 	ce = i915_gem_context_get_engine(ctx, BCS0);
 	GEM_BUG_ON(IS_ERR(ce));
 
+	total = ce->vm->total;
+
+	/*
+	 * If we have a tiny shared address space, like for the GGTT
+	 * then we can't be too greedy.
+	 */
+	if (i915_is_ggtt(ce->vm)) {
+		total >>= 4; /* Dumb heuristic */
+		total = div64_u64(total, thread->n_cpus);
+	}
+
 	do {
 		const u32 max_block_size = S16_MAX * PAGE_SIZE;
 		u32 val = prandom_u32_state(prng);
-		u64 total = ce->vm->total;
 		u32 phys_sz;
 		u32 sz;
 		u32 *vaddr;
 		u32 i;
 
-		/*
-		 * If we have a tiny shared address space, like for the GGTT
-		 * then we can't be too greedy.
-		 */
-		if (i915_is_ggtt(ce->vm))
-			total = div64_u64(total, thread->n_cpus);
-
-		sz = min_t(u64, total >> 4, prandom_u32_state(prng));
+		GEM_BUG_ON(total < PAGE_SIZE);
+		sz = min_t(u64, total, prandom_u32_state(prng));
 		phys_sz = sz % (max_block_size + 1);
 
-		sz = round_up(sz, PAGE_SIZE);
-		phys_sz = round_up(phys_sz, PAGE_SIZE);
+		sz = max_t(u32, round_up(sz, PAGE_SIZE), PAGE_SIZE);
+		phys_sz = max_t(u32, round_up(phys_sz, PAGE_SIZE), PAGE_SIZE);
 
 		pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__,
 			 phys_sz, sz, val);
@@ -267,8 +272,19 @@ static int igt_fill_blt_thread(void *arg)
 			obj->cache_dirty = true;
 
 		err = i915_gem_object_fill_blt(obj, ce, val);
-		if (err)
+		if (err) {
+			/*
+			 * The ggtt may have some pages reserved so refrain
+			 * from erroring out. Simply reduce the size and try
+			 * again if we have time.
+			 */
+			if (err == -ENOSPC && i915_is_ggtt(ce->vm)) {
+				total = sz >> 1;
+				err = 0;
+			}
+
 			goto err_unpin;
+		}
 
 		i915_gem_object_lock(obj);
 		err = i915_gem_object_set_to_cpu_domain(obj, false);
@@ -284,17 +300,17 @@ static int igt_fill_blt_thread(void *arg)
 				goto err_unpin;
 			}
 		}
-
+err_unpin:
 		i915_gem_object_unpin_map(obj);
+err_put:
 		i915_gem_object_put(obj);
-	} while (!time_after(jiffies, end));
+
+		if (err || time_after(jiffies, end))
+			break;
+	} while (1);
 
 	goto err_flush;
 
-err_unpin:
-	i915_gem_object_unpin_map(obj);
-err_put:
-	i915_gem_object_put(obj);
 err_flush:
 	if (err == -ENOMEM)
 		err = 0;
@@ -316,6 +332,7 @@ static int igt_copy_blt_thread(void *arg)
 	struct drm_file *file;
 	unsigned int prio;
 	IGT_TIMEOUT(end);
+	u64 total;
 	int err;
 
 	file = mock_file(i915);
@@ -334,23 +351,27 @@ static int igt_copy_blt_thread(void *arg)
 	ce = i915_gem_context_get_engine(ctx, BCS0);
 	GEM_BUG_ON(IS_ERR(ce));
 
+	total = ce->vm->total >> 1; /* We need to fit src and dst */
+
+	if (i915_is_ggtt(ce->vm)) {
+		total >>= 4;
+		total = div64_u64(total, thread->n_cpus);
+	}
+
 	do {
 		const u32 max_block_size = S16_MAX * PAGE_SIZE;
 		u32 val = prandom_u32_state(prng);
-		u64 total = ce->vm->total;
 		u32 phys_sz;
 		u32 sz;
 		u32 *vaddr;
 		u32 i;
 
-		if (i915_is_ggtt(ce->vm))
-			total = div64_u64(total, thread->n_cpus);
-
-		sz = min_t(u64, total >> 4, prandom_u32_state(prng));
+		GEM_BUG_ON(total < 2 * PAGE_SIZE);
+		sz = min_t(u64, total, prandom_u32_state(prng));
 		phys_sz = sz % (max_block_size + 1);
 
-		sz = round_up(sz, PAGE_SIZE);
-		phys_sz = round_up(phys_sz, PAGE_SIZE);
+		sz = max_t(u32, round_up(sz, PAGE_SIZE), PAGE_SIZE);
+		phys_sz = max_t(u32, round_up(phys_sz, PAGE_SIZE), PAGE_SIZE);
 
 		pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__,
 			 phys_sz, sz, val);
@@ -394,8 +415,19 @@ static int igt_copy_blt_thread(void *arg)
 			dst->cache_dirty = true;
 
 		err = i915_gem_object_copy_blt(src, dst, ce);
-		if (err)
+		if (err) {
+			/*
+			 * The ggtt may have some pages reserved so refrain
+			 * from erroring out. Simply reduce the size and try
+			 * again if we have time.
+			 */
+			if (err == -ENOSPC && i915_is_ggtt(ce->vm)) {
+				total = sz >> 1;
+				err = 0;
+			}
+
 			goto err_unpin;
+		}
 
 		i915_gem_object_lock(dst);
 		err = i915_gem_object_set_to_cpu_domain(dst, false);
@@ -411,21 +443,19 @@ static int igt_copy_blt_thread(void *arg)
 				goto err_unpin;
 			}
 		}
-
+err_unpin:
 		i915_gem_object_unpin_map(dst);
-
-		i915_gem_object_put(src);
+err_put_dst:
 		i915_gem_object_put(dst);
-	} while (!time_after(jiffies, end));
+err_put_src:
+		i915_gem_object_put(src);
+
+		if (err || time_after(jiffies, end))
+			break;
+	} while (0);
 
 	goto err_flush;
 
-err_unpin:
-	i915_gem_object_unpin_map(dst);
-err_put_dst:
-	i915_gem_object_put(dst);
-err_put_src:
-	i915_gem_object_put(src);
 err_flush:
 	if (err == -ENOMEM)
 		err = 0;
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list