From 992d2098ef0bc1256016fec86e4082524e2f52cc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Oct 2018 13:32:01 +0100 Subject: [PATCH] drm/i915/selftests: Split preemption smoke test into threads When submitting chains to each engine, we can do so (mostly) in parallel, so delegate submission to threads on a per-engine basis. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20181001123204.23982-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/intel_lrc.c | 73 +++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 3a474bb64c05..d68a924c530e 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -587,8 +587,10 @@ static int random_priority(struct rnd_state *rnd) struct preempt_smoke { struct drm_i915_private *i915; struct i915_gem_context **contexts; + struct intel_engine_cs *engine; unsigned int ncontext; struct rnd_state prng; + unsigned long count; }; static struct i915_gem_context *smoke_context(struct preempt_smoke *smoke) @@ -597,31 +599,78 @@ static struct i915_gem_context *smoke_context(struct preempt_smoke *smoke) &smoke->prng)]; } +static int smoke_crescendo_thread(void *arg) +{ + struct preempt_smoke *smoke = arg; + IGT_TIMEOUT(end_time); + unsigned long count; + + count = 0; + do { + struct i915_gem_context *ctx = smoke_context(smoke); + struct i915_request *rq; + + mutex_lock(&smoke->i915->drm.struct_mutex); + + ctx->sched.priority = count % I915_PRIORITY_MAX; + + rq = i915_request_alloc(smoke->engine, ctx); + if (IS_ERR(rq)) { + mutex_unlock(&smoke->i915->drm.struct_mutex); + return PTR_ERR(rq); + } + + i915_request_add(rq); + + mutex_unlock(&smoke->i915->drm.struct_mutex); + + count++; + } while (!__igt_timeout(end_time, NULL)); + + smoke->count = count; + return 0; +} + static int smoke_crescendo(struct preempt_smoke *smoke) { + struct task_struct *tsk[I915_NUM_ENGINES] = {}; + struct preempt_smoke arg[I915_NUM_ENGINES]; struct intel_engine_cs *engine; enum intel_engine_id id; unsigned long count; + int err = 0; + + mutex_unlock(&smoke->i915->drm.struct_mutex); - count = 0; for_each_engine(engine, smoke->i915, id) { - IGT_TIMEOUT(end_time); + arg[id] = *smoke; + arg[id].engine = engine; + arg[id].count = 0; + + tsk[id] = kthread_run(smoke_crescendo_thread, &arg, + "igt/smoke:%d", id); + if (IS_ERR(tsk[id])) { + err = PTR_ERR(tsk[id]); + break; + } + } - do { - struct i915_gem_context *ctx = smoke_context(smoke); - struct i915_request *rq; + count = 0; + for_each_engine(engine, smoke->i915, id) { + int status; - ctx->sched.priority = count % I915_PRIORITY_MAX; + if (IS_ERR_OR_NULL(tsk[id])) + continue; - rq = i915_request_alloc(engine, ctx); - if (IS_ERR(rq)) - return PTR_ERR(rq); + status = kthread_stop(tsk[id]); + if (status && !err) + err = status; - i915_request_add(rq); - count++; - } while (!__igt_timeout(end_time, NULL)); + count += arg[id].count; } + mutex_lock(&smoke->i915->drm.struct_mutex); + pr_info("Submitted %lu crescendo requests across %d engines and %d contexts\n", count, INTEL_INFO(smoke->i915)->num_rings, smoke->ncontext); return 0; -- 2.11.0