Commit 34485832 authored by Chris Wilson's avatar Chris Wilson

drm/i915/selftests: Exercise parallel blit operations on a single ctx

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=112176Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191111122706.28292-1-chris@chris-wilson.co.uk
parent e88866ef
...@@ -186,6 +186,8 @@ static int perf_copy_blt(void *arg) ...@@ -186,6 +186,8 @@ static int perf_copy_blt(void *arg)
struct igt_thread_arg { struct igt_thread_arg {
struct drm_i915_private *i915; struct drm_i915_private *i915;
struct i915_gem_context *ctx;
struct file *file;
struct rnd_state prng; struct rnd_state prng;
unsigned int n_cpus; unsigned int n_cpus;
}; };
...@@ -198,24 +200,20 @@ static int igt_fill_blt_thread(void *arg) ...@@ -198,24 +200,20 @@ static int igt_fill_blt_thread(void *arg)
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
struct intel_context *ce; struct intel_context *ce;
struct file *file;
unsigned int prio; unsigned int prio;
IGT_TIMEOUT(end); IGT_TIMEOUT(end);
int err; int err;
file = mock_file(i915); ctx = thread->ctx;
if (IS_ERR(file)) if (!ctx) {
return PTR_ERR(file); ctx = live_context(i915, thread->file);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
ctx = live_context(i915, file); prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
if (IS_ERR(ctx)) { ctx->sched.priority = I915_USER_PRIORITY(prio);
err = PTR_ERR(ctx);
goto out_file;
} }
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); ce = i915_gem_context_get_engine(ctx, BCS0);
GEM_BUG_ON(IS_ERR(ce)); GEM_BUG_ON(IS_ERR(ce));
...@@ -300,8 +298,6 @@ static int igt_fill_blt_thread(void *arg) ...@@ -300,8 +298,6 @@ static int igt_fill_blt_thread(void *arg)
err = 0; err = 0;
intel_context_put(ce); intel_context_put(ce);
out_file:
fput(file);
return err; return err;
} }
...@@ -313,24 +309,20 @@ static int igt_copy_blt_thread(void *arg) ...@@ -313,24 +309,20 @@ static int igt_copy_blt_thread(void *arg)
struct drm_i915_gem_object *src, *dst; struct drm_i915_gem_object *src, *dst;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
struct intel_context *ce; struct intel_context *ce;
struct file *file;
unsigned int prio; unsigned int prio;
IGT_TIMEOUT(end); IGT_TIMEOUT(end);
int err; int err;
file = mock_file(i915); ctx = thread->ctx;
if (IS_ERR(file)) if (!ctx) {
return PTR_ERR(file); ctx = live_context(i915, thread->file);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
ctx = live_context(i915, file); prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng);
if (IS_ERR(ctx)) { ctx->sched.priority = I915_USER_PRIORITY(prio);
err = PTR_ERR(ctx);
goto out_file;
} }
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); ce = i915_gem_context_get_engine(ctx, BCS0);
GEM_BUG_ON(IS_ERR(ce)); GEM_BUG_ON(IS_ERR(ce));
...@@ -431,19 +423,19 @@ static int igt_copy_blt_thread(void *arg) ...@@ -431,19 +423,19 @@ static int igt_copy_blt_thread(void *arg)
err = 0; err = 0;
intel_context_put(ce); intel_context_put(ce);
out_file:
fput(file);
return err; return err;
} }
static int igt_threaded_blt(struct drm_i915_private *i915, 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 igt_thread_arg *thread;
struct task_struct **tsk; struct task_struct **tsk;
unsigned int n_cpus, i;
I915_RND_STATE(prng); I915_RND_STATE(prng);
unsigned int n_cpus; struct file *file;
unsigned int i;
int err = 0; int err = 0;
n_cpus = num_online_cpus() + 1; n_cpus = num_online_cpus() + 1;
...@@ -453,13 +445,27 @@ static int igt_threaded_blt(struct drm_i915_private *i915, ...@@ -453,13 +445,27 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
return 0; return 0;
thread = kcalloc(n_cpus, sizeof(struct igt_thread_arg), GFP_KERNEL); thread = kcalloc(n_cpus, sizeof(struct igt_thread_arg), GFP_KERNEL);
if (!thread) { if (!thread)
kfree(tsk); goto out_tsk;
return 0;
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) { for (i = 0; i < n_cpus; ++i) {
thread[i].i915 = i915; thread[i].i915 = i915;
thread[i].file = thread[0].file;
thread[i].ctx = thread[0].ctx;
thread[i].n_cpus = n_cpus; thread[i].n_cpus = n_cpus;
thread[i].prng = thread[i].prng =
I915_RND_STATE_INITIALIZER(prandom_u32_state(&prng)); I915_RND_STATE_INITIALIZER(prandom_u32_state(&prng));
...@@ -488,20 +494,33 @@ static int igt_threaded_blt(struct drm_i915_private *i915, ...@@ -488,20 +494,33 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
put_task_struct(tsk[i]); put_task_struct(tsk[i]);
} }
kfree(tsk); out_file:
fput(thread[0].file);
out_thread:
kfree(thread); kfree(thread);
out_tsk:
kfree(tsk);
return err; return err;
} }
static int igt_fill_blt(void *arg) 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) 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) int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915)
...@@ -510,7 +529,9 @@ int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915) ...@@ -510,7 +529,9 @@ int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915)
SUBTEST(perf_fill_blt), SUBTEST(perf_fill_blt),
SUBTEST(perf_copy_blt), SUBTEST(perf_copy_blt),
SUBTEST(igt_fill_blt), SUBTEST(igt_fill_blt),
SUBTEST(igt_fill_blt_ctx0),
SUBTEST(igt_copy_blt), SUBTEST(igt_copy_blt),
SUBTEST(igt_copy_blt_ctx0),
}; };
if (intel_gt_is_wedged(&i915->gt)) if (intel_gt_is_wedged(&i915->gt))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment