drm/i915: Mock infrastructure for request emission
Create a fake engine that runs requests using a timer to simulate hw. v2: Prevent leaks of ctx->name along error paths Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170213171558.20942-8-chris@chris-wilson.co.uk
This commit is contained in:
		
							parent
							
								
									3b5bb0a376
								
							
						
					
					
						commit
						0daf0113cf
					
				| @ -1199,3 +1199,7 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) | ||||
| #include "selftests/mock_context.c" | ||||
| #endif | ||||
|  | ||||
| @ -25,6 +25,7 @@ | ||||
| #include "../i915_selftest.h" | ||||
| #include "i915_random.h" | ||||
| 
 | ||||
| #include "mock_gem_device.h" | ||||
| #include "mock_engine.h" | ||||
| 
 | ||||
| static int check_rbtree(struct intel_engine_cs *engine, | ||||
| @ -466,15 +467,15 @@ int intel_breadcrumbs_mock_selftests(void) | ||||
| 		SUBTEST(igt_insert_complete), | ||||
| 		SUBTEST(igt_wakeup), | ||||
| 	}; | ||||
| 	struct intel_engine_cs *engine; | ||||
| 	struct drm_i915_private *i915; | ||||
| 	int err; | ||||
| 
 | ||||
| 	engine = mock_engine("mock"); | ||||
| 	if (!engine) | ||||
| 	i915 = mock_gem_device(); | ||||
| 	if (!i915) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	err = i915_subtests(tests, engine); | ||||
| 	kfree(engine); | ||||
| 	err = i915_subtests(tests, i915->engine[RCS]); | ||||
| 	drm_dev_unref(&i915->drm); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
							
								
								
									
										78
									
								
								drivers/gpu/drm/i915/selftests/mock_context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								drivers/gpu/drm/i915/selftests/mock_context.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | ||||
| /*
 | ||||
|  * Copyright © 2016 Intel Corporation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the next | ||||
|  * paragraph) shall be included in all copies or substantial portions of the | ||||
|  * Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "mock_context.h" | ||||
| #include "mock_gtt.h" | ||||
| 
 | ||||
| struct i915_gem_context * | ||||
| mock_context(struct drm_i915_private *i915, | ||||
| 	     const char *name) | ||||
| { | ||||
| 	struct i915_gem_context *ctx; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||||
| 	if (!ctx) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	kref_init(&ctx->ref); | ||||
| 	INIT_LIST_HEAD(&ctx->link); | ||||
| 	ctx->i915 = i915; | ||||
| 
 | ||||
| 	ret = ida_simple_get(&i915->context_hw_ida, | ||||
| 			     0, MAX_CONTEXT_HW_ID, GFP_KERNEL); | ||||
| 	if (ret < 0) | ||||
| 		goto err_free; | ||||
| 	ctx->hw_id = ret; | ||||
| 
 | ||||
| 	if (name) { | ||||
| 		ctx->name = kstrdup(name, GFP_KERNEL); | ||||
| 		if (!ctx->name) | ||||
| 			goto err_put; | ||||
| 
 | ||||
| 		ctx->ppgtt = mock_ppgtt(i915, name); | ||||
| 		if (!ctx->ppgtt) | ||||
| 			goto err_put; | ||||
| 	} | ||||
| 
 | ||||
| 	return ctx; | ||||
| 
 | ||||
| err_free: | ||||
| 	kfree(ctx); | ||||
| 	return NULL; | ||||
| 
 | ||||
| err_put: | ||||
| 	i915_gem_context_set_closed(ctx); | ||||
| 	i915_gem_context_put(ctx); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| void mock_context_close(struct i915_gem_context *ctx) | ||||
| { | ||||
| 	i915_gem_context_set_closed(ctx); | ||||
| 
 | ||||
| 	i915_ppgtt_close(&ctx->ppgtt->base); | ||||
| 
 | ||||
| 	i915_gem_context_put(ctx); | ||||
| } | ||||
							
								
								
									
										34
									
								
								drivers/gpu/drm/i915/selftests/mock_context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								drivers/gpu/drm/i915/selftests/mock_context.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| /*
 | ||||
|  * Copyright © 2016 Intel Corporation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the next | ||||
|  * paragraph) shall be included in all copies or substantial portions of the | ||||
|  * Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __MOCK_CONTEXT_H | ||||
| #define __MOCK_CONTEXT_H | ||||
| 
 | ||||
| struct i915_gem_context * | ||||
| mock_context(struct drm_i915_private *i915, | ||||
| 	     const char *name); | ||||
| 
 | ||||
| void mock_context_close(struct i915_gem_context *ctx); | ||||
| 
 | ||||
| #endif /* !__MOCK_CONTEXT_H */ | ||||
| @ -23,33 +23,185 @@ | ||||
|  */ | ||||
| 
 | ||||
| #include "mock_engine.h" | ||||
| #include "mock_request.h" | ||||
| 
 | ||||
| struct intel_engine_cs *mock_engine(const char *name) | ||||
| static struct mock_request *first_request(struct mock_engine *engine) | ||||
| { | ||||
| 	struct intel_engine_cs *engine; | ||||
| 	return list_first_entry_or_null(&engine->hw_queue, | ||||
| 					struct mock_request, | ||||
| 					link); | ||||
| } | ||||
| 
 | ||||
| static void hw_delay_complete(unsigned long data) | ||||
| { | ||||
| 	struct mock_engine *engine = (typeof(engine))data; | ||||
| 	struct mock_request *request; | ||||
| 
 | ||||
| 	spin_lock(&engine->hw_lock); | ||||
| 
 | ||||
| 	request = first_request(engine); | ||||
| 	if (request) { | ||||
| 		list_del_init(&request->link); | ||||
| 		mock_seqno_advance(&engine->base, request->base.global_seqno); | ||||
| 	} | ||||
| 
 | ||||
| 	request = first_request(engine); | ||||
| 	if (request) | ||||
| 		mod_timer(&engine->hw_delay, jiffies + request->delay); | ||||
| 
 | ||||
| 	spin_unlock(&engine->hw_lock); | ||||
| } | ||||
| 
 | ||||
| static int mock_context_pin(struct intel_engine_cs *engine, | ||||
| 			    struct i915_gem_context *ctx) | ||||
| { | ||||
| 	i915_gem_context_get(ctx); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void mock_context_unpin(struct intel_engine_cs *engine, | ||||
| 			       struct i915_gem_context *ctx) | ||||
| { | ||||
| 	i915_gem_context_put(ctx); | ||||
| } | ||||
| 
 | ||||
| static int mock_request_alloc(struct drm_i915_gem_request *request) | ||||
| { | ||||
| 	struct mock_request *mock = container_of(request, typeof(*mock), base); | ||||
| 
 | ||||
| 	INIT_LIST_HEAD(&mock->link); | ||||
| 	mock->delay = 0; | ||||
| 
 | ||||
| 	request->ring = request->engine->buffer; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int mock_emit_flush(struct drm_i915_gem_request *request, | ||||
| 			   unsigned int flags) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void mock_emit_breadcrumb(struct drm_i915_gem_request *request, | ||||
| 				 u32 *flags) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static void mock_submit_request(struct drm_i915_gem_request *request) | ||||
| { | ||||
| 	struct mock_request *mock = container_of(request, typeof(*mock), base); | ||||
| 	struct mock_engine *engine = | ||||
| 		container_of(request->engine, typeof(*engine), base); | ||||
| 
 | ||||
| 	i915_gem_request_submit(request); | ||||
| 	GEM_BUG_ON(!request->global_seqno); | ||||
| 
 | ||||
| 	spin_lock_irq(&engine->hw_lock); | ||||
| 	list_add_tail(&mock->link, &engine->hw_queue); | ||||
| 	if (mock->link.prev == &engine->hw_queue) | ||||
| 		mod_timer(&engine->hw_delay, jiffies + mock->delay); | ||||
| 	spin_unlock_irq(&engine->hw_lock); | ||||
| } | ||||
| 
 | ||||
| static struct intel_ring *mock_ring(struct intel_engine_cs *engine) | ||||
| { | ||||
| 	const unsigned long sz = roundup_pow_of_two(sizeof(struct intel_ring)); | ||||
| 	struct intel_ring *ring; | ||||
| 
 | ||||
| 	ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); | ||||
| 	if (!ring) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	ring->engine = engine; | ||||
| 	ring->size = sz; | ||||
| 	ring->effective_size = sz; | ||||
| 	ring->vaddr = (void *)(ring + 1); | ||||
| 
 | ||||
| 	INIT_LIST_HEAD(&ring->request_list); | ||||
| 	ring->last_retired_head = -1; | ||||
| 	intel_ring_update_space(ring); | ||||
| 
 | ||||
| 	return ring; | ||||
| } | ||||
| 
 | ||||
| struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, | ||||
| 				    const char *name) | ||||
| { | ||||
| 	struct mock_engine *engine; | ||||
| 	static int id; | ||||
| 
 | ||||
| 	engine = kzalloc(sizeof(*engine) + PAGE_SIZE, GFP_KERNEL); | ||||
| 	if (!engine) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/* minimal engine setup for seqno */ | ||||
| 	engine->name = name; | ||||
| 	engine->id = id++; | ||||
| 	engine->status_page.page_addr = (void *)(engine + 1); | ||||
| 	engine->base.buffer = mock_ring(&engine->base); | ||||
| 	if (!engine->base.buffer) { | ||||
| 		kfree(engine); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* minimal breadcrumbs init */ | ||||
| 	spin_lock_init(&engine->breadcrumbs.lock); | ||||
| 	engine->breadcrumbs.mock = true; | ||||
| 	/* minimal engine setup for requests */ | ||||
| 	engine->base.i915 = i915; | ||||
| 	engine->base.name = name; | ||||
| 	engine->base.id = id++; | ||||
| 	engine->base.status_page.page_addr = (void *)(engine + 1); | ||||
| 
 | ||||
| 	return engine; | ||||
| 	engine->base.context_pin = mock_context_pin; | ||||
| 	engine->base.context_unpin = mock_context_unpin; | ||||
| 	engine->base.request_alloc = mock_request_alloc; | ||||
| 	engine->base.emit_flush = mock_emit_flush; | ||||
| 	engine->base.emit_breadcrumb = mock_emit_breadcrumb; | ||||
| 	engine->base.submit_request = mock_submit_request; | ||||
| 
 | ||||
| 	engine->base.timeline = | ||||
| 		&i915->gt.global_timeline.engine[engine->base.id]; | ||||
| 
 | ||||
| 	intel_engine_init_breadcrumbs(&engine->base); | ||||
| 	engine->base.breadcrumbs.mock = true; /* prevent touching HW for irqs */ | ||||
| 
 | ||||
| 	/* fake hw queue */ | ||||
| 	spin_lock_init(&engine->hw_lock); | ||||
| 	setup_timer(&engine->hw_delay, | ||||
| 		    hw_delay_complete, | ||||
| 		    (unsigned long)engine); | ||||
| 	INIT_LIST_HEAD(&engine->hw_queue); | ||||
| 
 | ||||
| 	return &engine->base; | ||||
| } | ||||
| 
 | ||||
| void mock_engine_flush(struct intel_engine_cs *engine) | ||||
| { | ||||
| 	struct mock_engine *mock = | ||||
| 		container_of(engine, typeof(*mock), base); | ||||
| 	struct mock_request *request, *rn; | ||||
| 
 | ||||
| 	del_timer_sync(&mock->hw_delay); | ||||
| 
 | ||||
| 	spin_lock_irq(&mock->hw_lock); | ||||
| 	list_for_each_entry_safe(request, rn, &mock->hw_queue, link) { | ||||
| 		list_del_init(&request->link); | ||||
| 		mock_seqno_advance(&mock->base, request->base.global_seqno); | ||||
| 	} | ||||
| 	spin_unlock_irq(&mock->hw_lock); | ||||
| } | ||||
| 
 | ||||
| void mock_engine_reset(struct intel_engine_cs *engine) | ||||
| { | ||||
| 	intel_write_status_page(engine, I915_GEM_HWS_INDEX, 0); | ||||
| } | ||||
| 
 | ||||
| void mock_engine_free(struct intel_engine_cs *engine) | ||||
| { | ||||
| 	struct mock_engine *mock = | ||||
| 		container_of(engine, typeof(*mock), base); | ||||
| 
 | ||||
| 	GEM_BUG_ON(timer_pending(&mock->hw_delay)); | ||||
| 
 | ||||
| 	if (engine->last_retired_context) | ||||
| 		engine->context_unpin(engine, engine->last_retired_context); | ||||
| 
 | ||||
| 	intel_engine_fini_breadcrumbs(engine); | ||||
| 
 | ||||
| 	kfree(engine->buffer); | ||||
| 	kfree(engine); | ||||
| } | ||||
|  | ||||
| @ -25,9 +25,25 @@ | ||||
| #ifndef __MOCK_ENGINE_H__ | ||||
| #define __MOCK_ENGINE_H__ | ||||
| 
 | ||||
| struct intel_engine_cs *mock_engine(const char *name); | ||||
| #include <linux/list.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/timer.h> | ||||
| 
 | ||||
| #include "../intel_ringbuffer.h" | ||||
| 
 | ||||
| struct mock_engine { | ||||
| 	struct intel_engine_cs base; | ||||
| 
 | ||||
| 	spinlock_t hw_lock; | ||||
| 	struct list_head hw_queue; | ||||
| 	struct timer_list hw_delay; | ||||
| }; | ||||
| 
 | ||||
| struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, | ||||
| 				    const char *name); | ||||
| void mock_engine_flush(struct intel_engine_cs *engine); | ||||
| void mock_engine_reset(struct intel_engine_cs *engine); | ||||
| void mock_engine_free(struct intel_engine_cs *engine); | ||||
| 
 | ||||
| static inline void mock_seqno_advance(struct intel_engine_cs *engine, u32 seqno) | ||||
| { | ||||
|  | ||||
| @ -24,14 +24,46 @@ | ||||
| 
 | ||||
| #include <linux/pm_runtime.h> | ||||
| 
 | ||||
| #include "mock_engine.h" | ||||
| #include "mock_context.h" | ||||
| #include "mock_request.h" | ||||
| #include "mock_gem_device.h" | ||||
| #include "mock_gem_object.h" | ||||
| #include "mock_gtt.h" | ||||
| 
 | ||||
| void mock_device_flush(struct drm_i915_private *i915) | ||||
| { | ||||
| 	struct intel_engine_cs *engine; | ||||
| 	enum intel_engine_id id; | ||||
| 
 | ||||
| 	lockdep_assert_held(&i915->drm.struct_mutex); | ||||
| 
 | ||||
| 	for_each_engine(engine, i915, id) | ||||
| 		mock_engine_flush(engine); | ||||
| 
 | ||||
| 	i915_gem_retire_requests(i915); | ||||
| } | ||||
| 
 | ||||
| static void mock_device_release(struct drm_device *dev) | ||||
| { | ||||
| 	struct drm_i915_private *i915 = to_i915(dev); | ||||
| 	struct intel_engine_cs *engine; | ||||
| 	enum intel_engine_id id; | ||||
| 
 | ||||
| 	mutex_lock(&i915->drm.struct_mutex); | ||||
| 	mock_device_flush(i915); | ||||
| 	mutex_unlock(&i915->drm.struct_mutex); | ||||
| 
 | ||||
| 	cancel_delayed_work_sync(&i915->gt.retire_work); | ||||
| 	cancel_delayed_work_sync(&i915->gt.idle_work); | ||||
| 
 | ||||
| 	mutex_lock(&i915->drm.struct_mutex); | ||||
| 	for_each_engine(engine, i915, id) | ||||
| 		mock_engine_free(engine); | ||||
| 	i915_gem_context_fini(i915); | ||||
| 	mutex_unlock(&i915->drm.struct_mutex); | ||||
| 
 | ||||
| 	drain_workqueue(i915->wq); | ||||
| 	i915_gem_drain_freed_objects(i915); | ||||
| 
 | ||||
| 	mutex_lock(&i915->drm.struct_mutex); | ||||
| @ -39,6 +71,10 @@ static void mock_device_release(struct drm_device *dev) | ||||
| 	i915_gem_timeline_fini(&i915->gt.global_timeline); | ||||
| 	mutex_unlock(&i915->drm.struct_mutex); | ||||
| 
 | ||||
| 	destroy_workqueue(i915->wq); | ||||
| 
 | ||||
| 	kmem_cache_destroy(i915->dependencies); | ||||
| 	kmem_cache_destroy(i915->requests); | ||||
| 	kmem_cache_destroy(i915->vmas); | ||||
| 	kmem_cache_destroy(i915->objects); | ||||
| 
 | ||||
| @ -62,9 +98,19 @@ static void release_dev(struct device *dev) | ||||
| 	kfree(pdev); | ||||
| } | ||||
| 
 | ||||
| static void mock_retire_work_handler(struct work_struct *work) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static void mock_idle_work_handler(struct work_struct *work) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| struct drm_i915_private *mock_gem_device(void) | ||||
| { | ||||
| 	struct drm_i915_private *i915; | ||||
| 	struct intel_engine_cs *engine; | ||||
| 	enum intel_engine_id id; | ||||
| 	struct pci_dev *pdev; | ||||
| 	int err; | ||||
| 
 | ||||
| @ -98,36 +144,81 @@ struct drm_i915_private *mock_gem_device(void) | ||||
| 
 | ||||
| 	spin_lock_init(&i915->mm.object_stat_lock); | ||||
| 
 | ||||
| 	init_waitqueue_head(&i915->gpu_error.wait_queue); | ||||
| 	init_waitqueue_head(&i915->gpu_error.reset_queue); | ||||
| 
 | ||||
| 	i915->wq = alloc_ordered_workqueue("mock", 0); | ||||
| 	if (!i915->wq) | ||||
| 		goto put_device; | ||||
| 
 | ||||
| 	INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); | ||||
| 	init_llist_head(&i915->mm.free_list); | ||||
| 	INIT_LIST_HEAD(&i915->mm.unbound_list); | ||||
| 	INIT_LIST_HEAD(&i915->mm.bound_list); | ||||
| 
 | ||||
| 	ida_init(&i915->context_hw_ida); | ||||
| 
 | ||||
| 	INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler); | ||||
| 	INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler); | ||||
| 
 | ||||
| 	i915->gt.awake = true; | ||||
| 
 | ||||
| 	i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN); | ||||
| 	if (!i915->objects) | ||||
| 		goto put_device; | ||||
| 		goto err_wq; | ||||
| 
 | ||||
| 	i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); | ||||
| 	if (!i915->vmas) | ||||
| 		goto err_objects; | ||||
| 
 | ||||
| 	i915->requests = KMEM_CACHE(mock_request, | ||||
| 				    SLAB_HWCACHE_ALIGN | | ||||
| 				    SLAB_RECLAIM_ACCOUNT | | ||||
| 				    SLAB_DESTROY_BY_RCU); | ||||
| 	if (!i915->requests) | ||||
| 		goto err_vmas; | ||||
| 
 | ||||
| 	i915->dependencies = KMEM_CACHE(i915_dependency, | ||||
| 					SLAB_HWCACHE_ALIGN | | ||||
| 					SLAB_RECLAIM_ACCOUNT); | ||||
| 	if (!i915->dependencies) | ||||
| 		goto err_requests; | ||||
| 
 | ||||
| 	mutex_lock(&i915->drm.struct_mutex); | ||||
| 	INIT_LIST_HEAD(&i915->gt.timelines); | ||||
| 	err = i915_gem_timeline_init__global(i915); | ||||
| 	if (err) { | ||||
| 		mutex_unlock(&i915->drm.struct_mutex); | ||||
| 		goto err_vmas; | ||||
| 		goto err_dependencies; | ||||
| 	} | ||||
| 
 | ||||
| 	mock_init_ggtt(i915); | ||||
| 	mutex_unlock(&i915->drm.struct_mutex); | ||||
| 
 | ||||
| 	mkwrite_device_info(i915)->ring_mask = BIT(0); | ||||
| 	i915->engine[RCS] = mock_engine(i915, "mock"); | ||||
| 	if (!i915->engine[RCS]) | ||||
| 		goto err_dependencies; | ||||
| 
 | ||||
| 	i915->kernel_context = mock_context(i915, NULL); | ||||
| 	if (!i915->kernel_context) | ||||
| 		goto err_engine; | ||||
| 
 | ||||
| 	return i915; | ||||
| 
 | ||||
| err_engine: | ||||
| 	for_each_engine(engine, i915, id) | ||||
| 		mock_engine_free(engine); | ||||
| err_dependencies: | ||||
| 	kmem_cache_destroy(i915->dependencies); | ||||
| err_requests: | ||||
| 	kmem_cache_destroy(i915->requests); | ||||
| err_vmas: | ||||
| 	kmem_cache_destroy(i915->vmas); | ||||
| err_objects: | ||||
| 	kmem_cache_destroy(i915->objects); | ||||
| err_wq: | ||||
| 	destroy_workqueue(i915->wq); | ||||
| put_device: | ||||
| 	put_device(&pdev->dev); | ||||
| err: | ||||
|  | ||||
| @ -4,5 +4,6 @@ | ||||
| struct drm_i915_private; | ||||
| 
 | ||||
| struct drm_i915_private *mock_gem_device(void); | ||||
| void mock_device_flush(struct drm_i915_private *i915); | ||||
| 
 | ||||
| #endif /* !__MOCK_GEM_DEVICE_H__ */ | ||||
|  | ||||
							
								
								
									
										44
									
								
								drivers/gpu/drm/i915/selftests/mock_request.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								drivers/gpu/drm/i915/selftests/mock_request.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /*
 | ||||
|  * Copyright © 2016 Intel Corporation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the next | ||||
|  * paragraph) shall be included in all copies or substantial portions of the | ||||
|  * Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "mock_request.h" | ||||
| 
 | ||||
| struct drm_i915_gem_request * | ||||
| mock_request(struct intel_engine_cs *engine, | ||||
| 	     struct i915_gem_context *context, | ||||
| 	     unsigned long delay) | ||||
| { | ||||
| 	struct drm_i915_gem_request *request; | ||||
| 	struct mock_request *mock; | ||||
| 
 | ||||
| 	/* NB the i915->requests slab cache is enlarged to fit mock_request */ | ||||
| 	request = i915_gem_request_alloc(engine, context); | ||||
| 	if (!request) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	mock = container_of(request, typeof(*mock), base); | ||||
| 	mock->delay = delay; | ||||
| 
 | ||||
| 	return &mock->base; | ||||
| } | ||||
							
								
								
									
										44
									
								
								drivers/gpu/drm/i915/selftests/mock_request.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								drivers/gpu/drm/i915/selftests/mock_request.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /*
 | ||||
|  * Copyright © 2016 Intel Corporation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the next | ||||
|  * paragraph) shall be included in all copies or substantial portions of the | ||||
|  * Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __MOCK_REQUEST__ | ||||
| #define __MOCK_REQUEST__ | ||||
| 
 | ||||
| #include <linux/list.h> | ||||
| 
 | ||||
| #include "../i915_gem_request.h" | ||||
| 
 | ||||
| struct mock_request { | ||||
| 	struct drm_i915_gem_request base; | ||||
| 
 | ||||
| 	struct list_head link; | ||||
| 	unsigned long delay; | ||||
| }; | ||||
| 
 | ||||
| struct drm_i915_gem_request * | ||||
| mock_request(struct intel_engine_cs *engine, | ||||
| 	     struct i915_gem_context *context, | ||||
| 	     unsigned long delay); | ||||
| 
 | ||||
| #endif /* !__MOCK_REQUEST__ */ | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user