mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	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=112176 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191111122706.28292-1-chris@chris-wilson.co.uk
This commit is contained in:
		
							parent
							
								
									e88866ef02
								
							
						
					
					
						commit
						34485832cb
					
				| @ -186,6 +186,8 @@ err_src: | |||||||
| 
 | 
 | ||||||
| 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,23 +200,19 @@ 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)) | ||||||
| 	ctx = live_context(i915, file); | 			return PTR_ERR(ctx); | ||||||
| 	if (IS_ERR(ctx)) { |  | ||||||
| 		err = PTR_ERR(ctx); |  | ||||||
| 		goto out_file; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 		prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng); | 		prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng); | ||||||
| 		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, BCS0); | ||||||
| 	GEM_BUG_ON(IS_ERR(ce)); | 	GEM_BUG_ON(IS_ERR(ce)); | ||||||
| @ -300,8 +298,6 @@ err_flush: | |||||||
| 		err = 0; | 		err = 0; | ||||||
| 
 | 
 | ||||||
| 	intel_context_put(ce); | 	intel_context_put(ce); | ||||||
| out_file: |  | ||||||
| 	fput(file); |  | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -313,23 +309,19 @@ 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)) | ||||||
| 	ctx = live_context(i915, file); | 			return PTR_ERR(ctx); | ||||||
| 	if (IS_ERR(ctx)) { |  | ||||||
| 		err = PTR_ERR(ctx); |  | ||||||
| 		goto out_file; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 		prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng); | 		prio = i915_prandom_u32_max_state(I915_PRIORITY_MAX, prng); | ||||||
| 		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, BCS0); | ||||||
| 	GEM_BUG_ON(IS_ERR(ce)); | 	GEM_BUG_ON(IS_ERR(ce)); | ||||||
| @ -431,19 +423,19 @@ err_flush: | |||||||
| 		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, | |||||||
| 		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, | |||||||
| 		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) | |||||||
| 		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)) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Chris Wilson
						Chris Wilson