diff options
Diffstat (limited to 'drivers/gpu/drm/i915/selftests/i915_request.c')
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_request.c | 129 | 
1 files changed, 111 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 8618a4dc0701..f89d9c42f1fa 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -27,11 +27,13 @@  #include "gem/i915_gem_pm.h"  #include "gem/selftests/mock_context.h" +#include "gt/intel_engine_pm.h"  #include "gt/intel_gt.h"  #include "i915_random.h"  #include "i915_selftest.h"  #include "igt_live_test.h" +#include "igt_spinner.h"  #include "lib_sw_fence.h"  #include "mock_drm.h" @@ -540,6 +542,7 @@ static int live_nop_request(void *arg)  		if (err)  			return err; +		intel_engine_pm_get(engine);  		for_each_prime_number_from(prime, 1, 8192) {  			struct i915_request *request = NULL; @@ -578,6 +581,7 @@ static int live_nop_request(void *arg)  			if (__igt_timeout(end_time, NULL))  				break;  		} +		intel_engine_pm_put(engine);  		err = igt_live_test_end(&t);  		if (err) @@ -692,10 +696,13 @@ static int live_empty_request(void *arg)  		if (err)  			goto out_batch; +		intel_engine_pm_get(engine); +  		/* Warmup / preload */  		request = empty_request(engine, batch);  		if (IS_ERR(request)) {  			err = PTR_ERR(request); +			intel_engine_pm_put(engine);  			goto out_batch;  		}  		i915_request_wait(request, 0, MAX_SCHEDULE_TIMEOUT); @@ -708,6 +715,7 @@ static int live_empty_request(void *arg)  				request = empty_request(engine, batch);  				if (IS_ERR(request)) {  					err = PTR_ERR(request); +					intel_engine_pm_put(engine);  					goto out_batch;  				}  			} @@ -721,6 +729,7 @@ static int live_empty_request(void *arg)  				break;  		}  		i915_request_put(request); +		intel_engine_pm_put(engine);  		err = igt_live_test_end(&t);  		if (err) @@ -740,10 +749,8 @@ out_batch:  static struct i915_vma *recursive_batch(struct drm_i915_private *i915)  { -	struct i915_gem_context *ctx = i915->kernel_context;  	struct drm_i915_gem_object *obj;  	const int gen = INTEL_GEN(i915); -	struct i915_address_space *vm;  	struct i915_vma *vma;  	u32 *cmd;  	int err; @@ -752,9 +759,7 @@ static struct i915_vma *recursive_batch(struct drm_i915_private *i915)  	if (IS_ERR(obj))  		return ERR_CAST(obj); -	vm = i915_gem_context_get_vm_rcu(ctx); -	vma = i915_vma_instance(obj, vm, NULL); -	i915_vm_put(vm); +	vma = i915_vma_instance(obj, i915->gt.vm, NULL);  	if (IS_ERR(vma)) {  		err = PTR_ERR(vma);  		goto err; @@ -845,7 +850,7 @@ static int live_all_engines(void *arg)  	idx = 0;  	for_each_uabi_engine(engine, i915) { -		request[idx] = i915_request_create(engine->kernel_context); +		request[idx] = intel_engine_create_kernel_request(engine);  		if (IS_ERR(request[idx])) {  			err = PTR_ERR(request[idx]);  			pr_err("%s: Request allocation failed with err=%d\n", @@ -962,7 +967,7 @@ static int live_sequential_engines(void *arg)  			goto out_free;  		} -		request[idx] = i915_request_create(engine->kernel_context); +		request[idx] = intel_engine_create_kernel_request(engine);  		if (IS_ERR(request[idx])) {  			err = PTR_ERR(request[idx]);  			pr_err("%s: Request allocation failed for %s with err=%d\n", @@ -1067,15 +1072,18 @@ static int __live_parallel_engine1(void *arg)  	struct intel_engine_cs *engine = arg;  	IGT_TIMEOUT(end_time);  	unsigned long count; +	int err = 0;  	count = 0; +	intel_engine_pm_get(engine);  	do {  		struct i915_request *rq; -		int err;  		rq = i915_request_create(engine->kernel_context); -		if (IS_ERR(rq)) -			return PTR_ERR(rq); +		if (IS_ERR(rq)) { +			err = PTR_ERR(rq); +			break; +		}  		i915_request_get(rq);  		i915_request_add(rq); @@ -1085,13 +1093,14 @@ static int __live_parallel_engine1(void *arg)  			err = -ETIME;  		i915_request_put(rq);  		if (err) -			return err; +			break;  		count++;  	} while (!__igt_timeout(end_time, NULL)); +	intel_engine_pm_put(engine);  	pr_info("%s: %lu request + sync\n", engine->name, count); -	return 0; +	return err;  }  static int __live_parallel_engineN(void *arg) @@ -1099,21 +1108,100 @@ static int __live_parallel_engineN(void *arg)  	struct intel_engine_cs *engine = arg;  	IGT_TIMEOUT(end_time);  	unsigned long count; +	int err = 0;  	count = 0; +	intel_engine_pm_get(engine);  	do {  		struct i915_request *rq;  		rq = i915_request_create(engine->kernel_context); -		if (IS_ERR(rq)) -			return PTR_ERR(rq); +		if (IS_ERR(rq)) { +			err = PTR_ERR(rq); +			break; +		}  		i915_request_add(rq);  		count++;  	} while (!__igt_timeout(end_time, NULL)); +	intel_engine_pm_put(engine);  	pr_info("%s: %lu requests\n", engine->name, count); -	return 0; +	return err; +} + +static bool wake_all(struct drm_i915_private *i915) +{ +	if (atomic_dec_and_test(&i915->selftest.counter)) { +		wake_up_var(&i915->selftest.counter); +		return true; +	} + +	return false; +} + +static int wait_for_all(struct drm_i915_private *i915) +{ +	if (wake_all(i915)) +		return 0; + +	if (wait_var_event_timeout(&i915->selftest.counter, +				   !atomic_read(&i915->selftest.counter), +				   i915_selftest.timeout_jiffies)) +		return 0; + +	return -ETIME; +} + +static int __live_parallel_spin(void *arg) +{ +	struct intel_engine_cs *engine = arg; +	struct igt_spinner spin; +	struct i915_request *rq; +	int err = 0; + +	/* +	 * Create a spinner running for eternity on each engine. If a second +	 * spinner is incorrectly placed on the same engine, it will not be +	 * able to start in time. +	 */ + +	if (igt_spinner_init(&spin, engine->gt)) { +		wake_all(engine->i915); +		return -ENOMEM; +	} + +	intel_engine_pm_get(engine); +	rq = igt_spinner_create_request(&spin, +					engine->kernel_context, +					MI_NOOP); /* no preemption */ +	intel_engine_pm_put(engine); +	if (IS_ERR(rq)) { +		err = PTR_ERR(rq); +		if (err == -ENODEV) +			err = 0; +		wake_all(engine->i915); +		goto out_spin; +	} + +	i915_request_get(rq); +	i915_request_add(rq); +	if (igt_wait_for_spinner(&spin, rq)) { +		/* Occupy this engine for the whole test */ +		err = wait_for_all(engine->i915); +	} else { +		pr_err("Failed to start spinner on %s\n", engine->name); +		err = -EINVAL; +	} +	igt_spinner_end(&spin); + +	if (err == 0 && i915_request_wait(rq, 0, HZ / 5) < 0) +		err = -EIO; +	i915_request_put(rq); + +out_spin: +	igt_spinner_fini(&spin); +	return err;  }  static int live_parallel_engines(void *arg) @@ -1122,6 +1210,7 @@ static int live_parallel_engines(void *arg)  	static int (* const func[])(void *arg) = {  		__live_parallel_engine1,  		__live_parallel_engineN, +		__live_parallel_spin,  		NULL,  	};  	const unsigned int nengines = num_uabi_engines(i915); @@ -1140,13 +1229,17 @@ static int live_parallel_engines(void *arg)  		return -ENOMEM;  	for (fn = func; !err && *fn; fn++) { +		char name[KSYM_NAME_LEN];  		struct igt_live_test t;  		unsigned int idx; -		err = igt_live_test_begin(&t, i915, __func__, ""); +		snprintf(name, sizeof(name), "%pS", fn); +		err = igt_live_test_begin(&t, i915, __func__, name);  		if (err)  			break; +		atomic_set(&i915->selftest.counter, nengines); +  		idx = 0;  		for_each_uabi_engine(engine, i915) {  			tsk[idx] = kthread_run(*fn, engine, @@ -1230,9 +1323,9 @@ static int live_breadcrumbs_smoketest(void *arg)  	struct task_struct **threads;  	struct igt_live_test live;  	intel_wakeref_t wakeref; -	struct drm_file *file;  	struct smoketest *smoke;  	unsigned int n, idx; +	struct file *file;  	int ret = 0;  	/* @@ -1354,7 +1447,7 @@ out_threads:  out_smoke:  	kfree(smoke);  out_file: -	mock_file_free(i915, file); +	fput(file);  out_rpm:  	intel_runtime_pm_put(&i915->runtime_pm, wakeref);  |