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.a...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
---
 .../i915/gem/selftests/i915_gem_object_blt.c  | 103 +++++++++++-------
 1 file changed, 61 insertions(+), 42 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..96fdf065061b 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);
@@ -247,7 +252,7 @@ static int igt_fill_blt_thread(void *arg)
                obj = huge_gem_object(i915, phys_sz, sz);
                if (IS_ERR(obj)) {
                        err = PTR_ERR(obj);
-                       goto err_flush;
+                       break;
                }
 
                vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
@@ -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,18 +300,15 @@ 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));
 
-       goto err_flush;
+               if (err)
+                       break;
+       } while (!time_after(jiffies, end));
 
-err_unpin:
-       i915_gem_object_unpin_map(obj);
-err_put:
-       i915_gem_object_put(obj);
-err_flush:
        if (err == -ENOMEM)
                err = 0;
 
@@ -316,6 +329,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 +348,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);
@@ -358,7 +376,7 @@ static int igt_copy_blt_thread(void *arg)
                src = huge_gem_object(i915, phys_sz, sz);
                if (IS_ERR(src)) {
                        err = PTR_ERR(src);
-                       goto err_flush;
+                       break;
                }
 
                vaddr = i915_gem_object_pin_map(src, I915_MAP_WB);
@@ -394,8 +412,14 @@ 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) {
+                       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,22 +435,17 @@ 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);
 
-       goto err_flush;
+               if (err)
+                       break;
+       } while (!time_after(jiffies, end));
 
-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

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

Reply via email to