Commit d61345f3 authored by Chris Wilson's avatar Chris Wilson

drm/i915/selftests: Exercise all copy engines with the blt routines

Just to remove an obnoxious HAS_ENGINES(), and in the process make the
code agnostic to the availabilty of any particular engine by making it
exercise any and all such engines declared on the system.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200604123641.767-1-chris@chris-wilson.co.uk
parent 34becfdb
...@@ -702,8 +702,5 @@ int i915_gem_client_blt_live_selftests(struct drm_i915_private *i915) ...@@ -702,8 +702,5 @@ int i915_gem_client_blt_live_selftests(struct drm_i915_private *i915)
if (intel_gt_is_wedged(&i915->gt)) if (intel_gt_is_wedged(&i915->gt))
return 0; return 0;
if (!HAS_ENGINE(i915, BCS0))
return 0;
return i915_live_subtests(tests, i915); return i915_live_subtests(tests, i915);
} }
...@@ -193,7 +193,7 @@ static int perf_copy_blt(void *arg) ...@@ -193,7 +193,7 @@ static int perf_copy_blt(void *arg)
} }
struct igt_thread_arg { struct igt_thread_arg {
struct drm_i915_private *i915; struct intel_engine_cs *engine;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
struct file *file; struct file *file;
struct rnd_state prng; struct rnd_state prng;
...@@ -203,7 +203,7 @@ struct igt_thread_arg { ...@@ -203,7 +203,7 @@ struct igt_thread_arg {
static int igt_fill_blt_thread(void *arg) static int igt_fill_blt_thread(void *arg)
{ {
struct igt_thread_arg *thread = arg; struct igt_thread_arg *thread = arg;
struct drm_i915_private *i915 = thread->i915; struct intel_engine_cs *engine = thread->engine;
struct rnd_state *prng = &thread->prng; struct rnd_state *prng = &thread->prng;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
...@@ -215,7 +215,7 @@ static int igt_fill_blt_thread(void *arg) ...@@ -215,7 +215,7 @@ static int igt_fill_blt_thread(void *arg)
ctx = thread->ctx; ctx = thread->ctx;
if (!ctx) { if (!ctx) {
ctx = live_context(i915, thread->file); ctx = live_context_for_engine(engine, thread->file);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return PTR_ERR(ctx);
...@@ -223,7 +223,7 @@ static int igt_fill_blt_thread(void *arg) ...@@ -223,7 +223,7 @@ static int igt_fill_blt_thread(void *arg)
ctx->sched.priority = I915_USER_PRIORITY(prio); ctx->sched.priority = I915_USER_PRIORITY(prio);
} }
ce = i915_gem_context_get_engine(ctx, BCS0); ce = i915_gem_context_get_engine(ctx, 0);
GEM_BUG_ON(IS_ERR(ce)); GEM_BUG_ON(IS_ERR(ce));
/* /*
...@@ -256,7 +256,7 @@ static int igt_fill_blt_thread(void *arg) ...@@ -256,7 +256,7 @@ static int igt_fill_blt_thread(void *arg)
pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__, pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__,
phys_sz, sz, val); phys_sz, sz, val);
obj = huge_gem_object(i915, phys_sz, sz); obj = huge_gem_object(engine->i915, phys_sz, sz);
if (IS_ERR(obj)) { if (IS_ERR(obj)) {
err = PTR_ERR(obj); err = PTR_ERR(obj);
goto err_flush; goto err_flush;
...@@ -321,7 +321,7 @@ static int igt_fill_blt_thread(void *arg) ...@@ -321,7 +321,7 @@ static int igt_fill_blt_thread(void *arg)
static int igt_copy_blt_thread(void *arg) static int igt_copy_blt_thread(void *arg)
{ {
struct igt_thread_arg *thread = arg; struct igt_thread_arg *thread = arg;
struct drm_i915_private *i915 = thread->i915; struct intel_engine_cs *engine = thread->engine;
struct rnd_state *prng = &thread->prng; struct rnd_state *prng = &thread->prng;
struct drm_i915_gem_object *src, *dst; struct drm_i915_gem_object *src, *dst;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
...@@ -333,7 +333,7 @@ static int igt_copy_blt_thread(void *arg) ...@@ -333,7 +333,7 @@ static int igt_copy_blt_thread(void *arg)
ctx = thread->ctx; ctx = thread->ctx;
if (!ctx) { if (!ctx) {
ctx = live_context(i915, thread->file); ctx = live_context_for_engine(engine, thread->file);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return PTR_ERR(ctx);
...@@ -341,7 +341,7 @@ static int igt_copy_blt_thread(void *arg) ...@@ -341,7 +341,7 @@ static int igt_copy_blt_thread(void *arg)
ctx->sched.priority = I915_USER_PRIORITY(prio); ctx->sched.priority = I915_USER_PRIORITY(prio);
} }
ce = i915_gem_context_get_engine(ctx, BCS0); ce = i915_gem_context_get_engine(ctx, 0);
GEM_BUG_ON(IS_ERR(ce)); GEM_BUG_ON(IS_ERR(ce));
/* /*
...@@ -374,7 +374,7 @@ static int igt_copy_blt_thread(void *arg) ...@@ -374,7 +374,7 @@ static int igt_copy_blt_thread(void *arg)
pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__, pr_debug("%s with phys_sz= %x, sz=%x, val=%x\n", __func__,
phys_sz, sz, val); phys_sz, sz, val);
src = huge_gem_object(i915, phys_sz, sz); src = huge_gem_object(engine->i915, phys_sz, sz);
if (IS_ERR(src)) { if (IS_ERR(src)) {
err = PTR_ERR(src); err = PTR_ERR(src);
goto err_flush; goto err_flush;
...@@ -394,7 +394,7 @@ static int igt_copy_blt_thread(void *arg) ...@@ -394,7 +394,7 @@ static int igt_copy_blt_thread(void *arg)
if (!(src->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) if (!(src->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
src->cache_dirty = true; src->cache_dirty = true;
dst = huge_gem_object(i915, phys_sz, sz); dst = huge_gem_object(engine->i915, phys_sz, sz);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
err = PTR_ERR(dst); err = PTR_ERR(dst);
goto err_put_src; goto err_put_src;
...@@ -456,7 +456,7 @@ static int igt_copy_blt_thread(void *arg) ...@@ -456,7 +456,7 @@ static int igt_copy_blt_thread(void *arg)
return err; return err;
} }
static int igt_threaded_blt(struct drm_i915_private *i915, static int igt_threaded_blt(struct intel_engine_cs *engine,
int (*blt_fn)(void *arg), int (*blt_fn)(void *arg),
unsigned int flags) unsigned int flags)
#define SINGLE_CTX BIT(0) #define SINGLE_CTX BIT(0)
...@@ -477,14 +477,14 @@ static int igt_threaded_blt(struct drm_i915_private *i915, ...@@ -477,14 +477,14 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
if (!thread) if (!thread)
goto out_tsk; goto out_tsk;
thread[0].file = mock_file(i915); thread[0].file = mock_file(engine->i915);
if (IS_ERR(thread[0].file)) { if (IS_ERR(thread[0].file)) {
err = PTR_ERR(thread[0].file); err = PTR_ERR(thread[0].file);
goto out_thread; goto out_thread;
} }
if (flags & SINGLE_CTX) { if (flags & SINGLE_CTX) {
thread[0].ctx = live_context(i915, thread[0].file); thread[0].ctx = live_context_for_engine(engine, thread[0].file);
if (IS_ERR(thread[0].ctx)) { if (IS_ERR(thread[0].ctx)) {
err = PTR_ERR(thread[0].ctx); err = PTR_ERR(thread[0].ctx);
goto out_file; goto out_file;
...@@ -492,7 +492,7 @@ static int igt_threaded_blt(struct drm_i915_private *i915, ...@@ -492,7 +492,7 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
} }
for (i = 0; i < n_cpus; ++i) { for (i = 0; i < n_cpus; ++i) {
thread[i].i915 = i915; thread[i].engine = engine;
thread[i].file = thread[0].file; thread[i].file = thread[0].file;
thread[i].ctx = thread[0].ctx; thread[i].ctx = thread[0].ctx;
thread[i].n_cpus = n_cpus; thread[i].n_cpus = n_cpus;
...@@ -532,24 +532,40 @@ static int igt_threaded_blt(struct drm_i915_private *i915, ...@@ -532,24 +532,40 @@ static int igt_threaded_blt(struct drm_i915_private *i915,
return err; return err;
} }
static int test_copy_engines(struct drm_i915_private *i915,
int (*fn)(void *arg),
unsigned int flags)
{
struct intel_engine_cs *engine;
int ret;
for_each_uabi_class_engine(engine, I915_ENGINE_CLASS_COPY, i915) {
ret = igt_threaded_blt(engine, fn, flags);
if (ret)
return ret;
}
return 0;
}
static int igt_fill_blt(void *arg) static int igt_fill_blt(void *arg)
{ {
return igt_threaded_blt(arg, igt_fill_blt_thread, 0); return test_copy_engines(arg, igt_fill_blt_thread, 0);
} }
static int igt_fill_blt_ctx0(void *arg) static int igt_fill_blt_ctx0(void *arg)
{ {
return igt_threaded_blt(arg, igt_fill_blt_thread, SINGLE_CTX); return test_copy_engines(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, 0); return test_copy_engines(arg, igt_copy_blt_thread, 0);
} }
static int igt_copy_blt_ctx0(void *arg) static int igt_copy_blt_ctx0(void *arg)
{ {
return igt_threaded_blt(arg, igt_copy_blt_thread, SINGLE_CTX); return test_copy_engines(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)
...@@ -564,9 +580,6 @@ int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915) ...@@ -564,9 +580,6 @@ int i915_gem_object_blt_live_selftests(struct drm_i915_private *i915)
if (intel_gt_is_wedged(&i915->gt)) if (intel_gt_is_wedged(&i915->gt))
return 0; return 0;
if (!HAS_ENGINE(i915, BCS0))
return 0;
return i915_live_subtests(tests, i915); return i915_live_subtests(tests, i915);
} }
......
...@@ -99,6 +99,43 @@ live_context(struct drm_i915_private *i915, struct file *file) ...@@ -99,6 +99,43 @@ live_context(struct drm_i915_private *i915, struct file *file)
return ERR_PTR(err); return ERR_PTR(err);
} }
struct i915_gem_context *
live_context_for_engine(struct intel_engine_cs *engine, struct file *file)
{
struct i915_gem_engines *engines;
struct i915_gem_context *ctx;
struct intel_context *ce;
engines = alloc_engines(1);
if (!engines)
return ERR_PTR(-ENOMEM);
ctx = live_context(engine->i915, file);
if (IS_ERR(ctx)) {
__free_engines(engines, 0);
return ctx;
}
ce = intel_context_create(engine);
if (IS_ERR(ce)) {
__free_engines(engines, 0);
return ERR_CAST(ce);
}
intel_context_set_gem(ce, ctx);
engines->engines[0] = ce;
engines->num_engines = 1;
mutex_lock(&ctx->engines_mutex);
i915_gem_context_set_user_engines(ctx);
engines = rcu_replace_pointer(ctx->engines, engines, 1);
mutex_unlock(&ctx->engines_mutex);
engines_idle_release(ctx, engines);
return ctx;
}
struct i915_gem_context * struct i915_gem_context *
kernel_context(struct drm_i915_private *i915) kernel_context(struct drm_i915_private *i915)
{ {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
struct file; struct file;
struct drm_i915_private; struct drm_i915_private;
struct intel_engine_cs;
void mock_init_contexts(struct drm_i915_private *i915); void mock_init_contexts(struct drm_i915_private *i915);
...@@ -21,6 +22,9 @@ void mock_context_close(struct i915_gem_context *ctx); ...@@ -21,6 +22,9 @@ void mock_context_close(struct i915_gem_context *ctx);
struct i915_gem_context * struct i915_gem_context *
live_context(struct drm_i915_private *i915, struct file *file); live_context(struct drm_i915_private *i915, struct file *file);
struct i915_gem_context *
live_context_for_engine(struct intel_engine_cs *engine, struct file *file);
struct i915_gem_context *kernel_context(struct drm_i915_private *i915); struct i915_gem_context *kernel_context(struct drm_i915_private *i915);
void kernel_context_close(struct i915_gem_context *ctx); void kernel_context_close(struct i915_gem_context *ctx);
......
...@@ -1261,6 +1261,11 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev) ...@@ -1261,6 +1261,11 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev)
(engine__); \ (engine__); \
(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node))) (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
#define for_each_uabi_class_engine(engine__, class__, i915__) \
for ((engine__) = intel_engine_lookup_user((i915__), (class__), 0); \
(engine__) && (engine__)->uabi_class == (class__); \
(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
#define I915_GTT_OFFSET_NONE ((u32)-1) #define I915_GTT_OFFSET_NONE ((u32)-1)
/* /*
......
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