Make sure that our code is robust enough to handle multiple threads
trying to clear objects for a single client context. This brings the joy
of a shared GGTT to all!

References: https://bugs.freedesktop.org/show_bug.cgi?id=112176
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Matthew Auld <matthew.a...@intel.com>
---
 .../i915/gem/selftests/i915_gem_object_blt.c  | 90 ++++++++++++-------
 1 file changed, 56 insertions(+), 34 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..1940f929290a 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
@@ -186,6 +186,8 @@ static int perf_copy_blt(void *arg)
 
 struct igt_thread_arg {
        struct drm_i915_private *i915;
+       struct i915_gem_context *ctx;
+       struct drm_file *file;
        struct rnd_state prng;
        unsigned int n_cpus;
 };
@@ -198,24 +200,20 @@ static int igt_fill_blt_thread(void *arg)
        struct drm_i915_gem_object *obj;
        struct i915_gem_context *ctx;
        struct intel_context *ce;
-       struct drm_file *file;
        unsigned int prio;
        IGT_TIMEOUT(end);
        int err;
 
-       file = mock_file(i915);
-       if (IS_ERR(file))
-               return PTR_ERR(file);
+       ctx = thread->ctx;
+       if (!ctx) {
+               ctx = live_context(i915, thread->file);
+               if (IS_ERR(ctx))
+                       return PTR_ERR(ctx);
 
-       ctx = live_context(i915, file);
-       if (IS_ERR(ctx)) {
-               err = PTR_ERR(ctx);
-               goto out_file;
+               prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
+               ctx->sched.priority = I915_USER_PRIORITY(prio);
        }
 
-       prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
-       ctx->sched.priority = I915_USER_PRIORITY(prio);
-
        ce = i915_gem_context_get_engine(ctx, BCS0);
        GEM_BUG_ON(IS_ERR(ce));
 
@@ -300,8 +298,6 @@ static int igt_fill_blt_thread(void *arg)
                err = 0;
 
        intel_context_put(ce);
-out_file:
-       mock_file_free(i915, file);
        return err;
 }
 
@@ -313,24 +309,20 @@ static int igt_copy_blt_thread(void *arg)
        struct drm_i915_gem_object *src, *dst;
        struct i915_gem_context *ctx;
        struct intel_context *ce;
-       struct drm_file *file;
        unsigned int prio;
        IGT_TIMEOUT(end);
        int err;
 
-       file = mock_file(i915);
-       if (IS_ERR(file))
-               return PTR_ERR(file);
+       ctx = thread->ctx;
+       if (!ctx) {
+               ctx = live_context(i915, thread->file);
+               if (IS_ERR(ctx))
+                       return PTR_ERR(ctx);
 
-       ctx = live_context(i915, file);
-       if (IS_ERR(ctx)) {
-               err = PTR_ERR(ctx);
-               goto out_file;
+               prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
+               ctx->sched.priority = I915_USER_PRIORITY(prio);
        }
 
-       prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
-       ctx->sched.priority = I915_USER_PRIORITY(prio);
-
        ce = i915_gem_context_get_engine(ctx, BCS0);
        GEM_BUG_ON(IS_ERR(ce));
 
@@ -431,16 +423,17 @@ static int igt_copy_blt_thread(void *arg)
                err = 0;
 
        intel_context_put(ce);
-out_file:
-       mock_file_free(i915, file);
        return err;
 }
 
 static int igt_threaded_blt(struct drm_i915_private *i915,
-                           int (*blt_fn)(void *arg))
+                           int (*blt_fn)(void *arg),
+                           unsigned int flags)
+#define SINGLE_CTX BIT(0)
 {
        struct igt_thread_arg *thread;
        struct task_struct **tsk;
+       struct drm_file *file;
        I915_RND_STATE(prng);
        unsigned int n_cpus;
        unsigned int i;
@@ -453,13 +446,27 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
                return 0;
 
        thread = kcalloc(n_cpus, sizeof(struct igt_thread_arg), GFP_KERNEL);
-       if (!thread) {
-               kfree(tsk);
-               return 0;
+       if (!thread)
+               goto out_tsk;
+
+       thread[0].file = mock_file(i915);
+       if (IS_ERR(thread[0].file)) {
+               err = PTR_ERR(file);
+               goto out_thread;
+       }
+
+       if (flags & SINGLE_CTX) {
+               thread[0].ctx = live_context(i915, thread[0].file);
+               if (IS_ERR(thread[0].ctx)) {
+                       err = PTR_ERR(thread[0].ctx);
+                       goto out_file;
+               }
        }
 
        for (i = 0; i < n_cpus; ++i) {
                thread[i].i915 = i915;
+               thread[i].file = thread[0].file;
+               thread[i].ctx = thread[0].ctx;
                thread[i].n_cpus = n_cpus;
                thread[i].prng =
                        I915_RND_STATE_INITIALIZER(prandom_u32_state(&prng));
@@ -488,20 +495,33 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
                put_task_struct(tsk[i]);
        }
 
-       kfree(tsk);
+out_file:
+       mock_file_free(i915, thread[0].file);
+out_thread:
        kfree(thread);
-
+out_tsk:
+       kfree(tsk);
        return err;
 }
 
 static int igt_fill_blt(void *arg)
 {
-       return igt_threaded_blt(arg, igt_fill_blt_thread);
+       return igt_threaded_blt(arg, igt_fill_blt_thread, 0);
+}
+
+static int igt_fill_blt_ctx0(void *arg)
+{
+       return igt_threaded_blt(arg, igt_fill_blt_thread, SINGLE_CTX);
 }
 
 static int igt_copy_blt(void *arg)
 {
-       return igt_threaded_blt(arg, igt_copy_blt_thread);
+       return igt_threaded_blt(arg, igt_copy_blt_thread, 0);
+}
+
+static int igt_copy_blt_ctx0(void *arg)
+{
+       return igt_threaded_blt(arg, igt_copy_blt_thread, SINGLE_CTX);
 }
 
 int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915)
@@ -510,7 +530,9 @@ int i915_gem_object_blt_live_selftests(struct 
drm_i915_private *i915)
                SUBTEST(perf_fill_blt),
                SUBTEST(perf_copy_blt),
                SUBTEST(igt_fill_blt),
+               SUBTEST(igt_fill_blt_ctx0),
                SUBTEST(igt_copy_blt),
+               SUBTEST(igt_copy_blt_ctx0),
        };
 
        if (intel_gt_is_wedged(&i915->gt))
-- 
2.24.0

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

Reply via email to