15ca02815Sjsg // SPDX-License-Identifier: MIT
2c349dbc7Sjsg /*
3c349dbc7Sjsg * Copyright © 2016 Intel Corporation
4c349dbc7Sjsg */
5c349dbc7Sjsg
6c349dbc7Sjsg #include "gem/i915_gem_context.h"
7c349dbc7Sjsg #include "gt/intel_ring.h"
8c349dbc7Sjsg
9c349dbc7Sjsg #include "i915_drv.h"
10c349dbc7Sjsg #include "intel_context.h"
11c349dbc7Sjsg #include "intel_engine_pm.h"
12c349dbc7Sjsg
13c349dbc7Sjsg #include "mock_engine.h"
14c349dbc7Sjsg #include "selftests/mock_request.h"
15c349dbc7Sjsg
mock_timeline_pin(struct intel_timeline * tl)165ca02815Sjsg static int mock_timeline_pin(struct intel_timeline *tl)
17c349dbc7Sjsg {
185ca02815Sjsg int err;
195ca02815Sjsg
20*1bb76ff1Sjsg if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj, NULL)))
215ca02815Sjsg return -EBUSY;
225ca02815Sjsg
235ca02815Sjsg err = intel_timeline_pin_map(tl);
245ca02815Sjsg i915_gem_object_unlock(tl->hwsp_ggtt->obj);
255ca02815Sjsg if (err)
265ca02815Sjsg return err;
275ca02815Sjsg
28c349dbc7Sjsg atomic_inc(&tl->pin_count);
295ca02815Sjsg return 0;
30c349dbc7Sjsg }
31c349dbc7Sjsg
mock_timeline_unpin(struct intel_timeline * tl)32c349dbc7Sjsg static void mock_timeline_unpin(struct intel_timeline *tl)
33c349dbc7Sjsg {
34c349dbc7Sjsg GEM_BUG_ON(!atomic_read(&tl->pin_count));
35c349dbc7Sjsg atomic_dec(&tl->pin_count);
36c349dbc7Sjsg }
37c349dbc7Sjsg
create_ring_vma(struct i915_ggtt * ggtt,int size)38*1bb76ff1Sjsg static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
39*1bb76ff1Sjsg {
40*1bb76ff1Sjsg struct i915_address_space *vm = &ggtt->vm;
41*1bb76ff1Sjsg struct drm_i915_private *i915 = vm->i915;
42*1bb76ff1Sjsg struct drm_i915_gem_object *obj;
43*1bb76ff1Sjsg struct i915_vma *vma;
44*1bb76ff1Sjsg
45*1bb76ff1Sjsg obj = i915_gem_object_create_internal(i915, size);
46*1bb76ff1Sjsg if (IS_ERR(obj))
47*1bb76ff1Sjsg return ERR_CAST(obj);
48*1bb76ff1Sjsg
49*1bb76ff1Sjsg vma = i915_vma_instance(obj, vm, NULL);
50*1bb76ff1Sjsg if (IS_ERR(vma))
51*1bb76ff1Sjsg goto err;
52*1bb76ff1Sjsg
53*1bb76ff1Sjsg return vma;
54*1bb76ff1Sjsg
55*1bb76ff1Sjsg err:
56*1bb76ff1Sjsg i915_gem_object_put(obj);
57*1bb76ff1Sjsg return vma;
58*1bb76ff1Sjsg }
59*1bb76ff1Sjsg
mock_ring(struct intel_engine_cs * engine)60c349dbc7Sjsg static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
61c349dbc7Sjsg {
62*1bb76ff1Sjsg const unsigned long sz = PAGE_SIZE;
63c349dbc7Sjsg struct intel_ring *ring;
64c349dbc7Sjsg
65c349dbc7Sjsg ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
66c349dbc7Sjsg if (!ring)
67c349dbc7Sjsg return NULL;
68c349dbc7Sjsg
69c349dbc7Sjsg kref_init(&ring->ref);
70c349dbc7Sjsg ring->size = sz;
71c349dbc7Sjsg ring->effective_size = sz;
72c349dbc7Sjsg ring->vaddr = (void *)(ring + 1);
73c349dbc7Sjsg atomic_set(&ring->pin_count, 1);
74c349dbc7Sjsg
75*1bb76ff1Sjsg ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
76*1bb76ff1Sjsg if (IS_ERR(ring->vma)) {
77c349dbc7Sjsg kfree(ring);
78c349dbc7Sjsg return NULL;
79c349dbc7Sjsg }
80c349dbc7Sjsg
81c349dbc7Sjsg intel_ring_update_space(ring);
82c349dbc7Sjsg
83c349dbc7Sjsg return ring;
84c349dbc7Sjsg }
85c349dbc7Sjsg
mock_ring_free(struct intel_ring * ring)86c349dbc7Sjsg static void mock_ring_free(struct intel_ring *ring)
87c349dbc7Sjsg {
88*1bb76ff1Sjsg i915_vma_put(ring->vma);
89c349dbc7Sjsg
90c349dbc7Sjsg kfree(ring);
91c349dbc7Sjsg }
92c349dbc7Sjsg
first_request(struct mock_engine * engine)93c349dbc7Sjsg static struct i915_request *first_request(struct mock_engine *engine)
94c349dbc7Sjsg {
95c349dbc7Sjsg return list_first_entry_or_null(&engine->hw_queue,
96c349dbc7Sjsg struct i915_request,
97c349dbc7Sjsg mock.link);
98c349dbc7Sjsg }
99c349dbc7Sjsg
advance(struct i915_request * request)100c349dbc7Sjsg static void advance(struct i915_request *request)
101c349dbc7Sjsg {
102c349dbc7Sjsg list_del_init(&request->mock.link);
103c349dbc7Sjsg i915_request_mark_complete(request);
104c349dbc7Sjsg GEM_BUG_ON(!i915_request_completed(request));
105c349dbc7Sjsg
106c349dbc7Sjsg intel_engine_signal_breadcrumbs(request->engine);
107c349dbc7Sjsg }
108c349dbc7Sjsg
hw_delay_complete(struct timer_list * t)109c349dbc7Sjsg static void hw_delay_complete(struct timer_list *t)
110c349dbc7Sjsg {
111c349dbc7Sjsg struct mock_engine *engine = from_timer(engine, t, hw_delay);
112c349dbc7Sjsg struct i915_request *request;
113c349dbc7Sjsg unsigned long flags;
114c349dbc7Sjsg
115c349dbc7Sjsg spin_lock_irqsave(&engine->hw_lock, flags);
116c349dbc7Sjsg
117c349dbc7Sjsg /* Timer fired, first request is complete */
118c349dbc7Sjsg request = first_request(engine);
119c349dbc7Sjsg if (request)
120c349dbc7Sjsg advance(request);
121c349dbc7Sjsg
122c349dbc7Sjsg /*
123c349dbc7Sjsg * Also immediately signal any subsequent 0-delay requests, but
124c349dbc7Sjsg * requeue the timer for the next delayed request.
125c349dbc7Sjsg */
126c349dbc7Sjsg while ((request = first_request(engine))) {
127c349dbc7Sjsg if (request->mock.delay) {
128c349dbc7Sjsg mod_timer(&engine->hw_delay,
129c349dbc7Sjsg jiffies + request->mock.delay);
130c349dbc7Sjsg break;
131c349dbc7Sjsg }
132c349dbc7Sjsg
133c349dbc7Sjsg advance(request);
134c349dbc7Sjsg }
135c349dbc7Sjsg
136c349dbc7Sjsg spin_unlock_irqrestore(&engine->hw_lock, flags);
137c349dbc7Sjsg }
138c349dbc7Sjsg
mock_context_unpin(struct intel_context * ce)139c349dbc7Sjsg static void mock_context_unpin(struct intel_context *ce)
140c349dbc7Sjsg {
141c349dbc7Sjsg }
142c349dbc7Sjsg
mock_context_post_unpin(struct intel_context * ce)143ad8b1aafSjsg static void mock_context_post_unpin(struct intel_context *ce)
144ad8b1aafSjsg {
145*1bb76ff1Sjsg i915_vma_unpin(ce->ring->vma);
146ad8b1aafSjsg }
147ad8b1aafSjsg
mock_context_destroy(struct kref * ref)148c349dbc7Sjsg static void mock_context_destroy(struct kref *ref)
149c349dbc7Sjsg {
150c349dbc7Sjsg struct intel_context *ce = container_of(ref, typeof(*ce), ref);
151c349dbc7Sjsg
152c349dbc7Sjsg GEM_BUG_ON(intel_context_is_pinned(ce));
153c349dbc7Sjsg
154c349dbc7Sjsg if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
155c349dbc7Sjsg mock_ring_free(ce->ring);
156c349dbc7Sjsg mock_timeline_unpin(ce->timeline);
157c349dbc7Sjsg }
158c349dbc7Sjsg
159c349dbc7Sjsg intel_context_fini(ce);
160c349dbc7Sjsg intel_context_free(ce);
161c349dbc7Sjsg }
162c349dbc7Sjsg
mock_context_alloc(struct intel_context * ce)163c349dbc7Sjsg static int mock_context_alloc(struct intel_context *ce)
164c349dbc7Sjsg {
1655ca02815Sjsg int err;
1665ca02815Sjsg
167c349dbc7Sjsg ce->ring = mock_ring(ce->engine);
168c349dbc7Sjsg if (!ce->ring)
169c349dbc7Sjsg return -ENOMEM;
170c349dbc7Sjsg
171ad8b1aafSjsg ce->timeline = intel_timeline_create(ce->engine->gt);
172c349dbc7Sjsg if (IS_ERR(ce->timeline)) {
173c349dbc7Sjsg kfree(ce->engine);
174c349dbc7Sjsg return PTR_ERR(ce->timeline);
175c349dbc7Sjsg }
176c349dbc7Sjsg
1775ca02815Sjsg err = mock_timeline_pin(ce->timeline);
1785ca02815Sjsg if (err) {
1795ca02815Sjsg intel_timeline_put(ce->timeline);
1805ca02815Sjsg ce->timeline = NULL;
1815ca02815Sjsg return err;
1825ca02815Sjsg }
183c349dbc7Sjsg
184c349dbc7Sjsg return 0;
185c349dbc7Sjsg }
186c349dbc7Sjsg
mock_context_pre_pin(struct intel_context * ce,struct i915_gem_ww_ctx * ww,void ** unused)187ad8b1aafSjsg static int mock_context_pre_pin(struct intel_context *ce,
188ad8b1aafSjsg struct i915_gem_ww_ctx *ww, void **unused)
189ad8b1aafSjsg {
190*1bb76ff1Sjsg return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
191ad8b1aafSjsg }
192ad8b1aafSjsg
mock_context_pin(struct intel_context * ce,void * unused)193ad8b1aafSjsg static int mock_context_pin(struct intel_context *ce, void *unused)
194c349dbc7Sjsg {
195c349dbc7Sjsg return 0;
196c349dbc7Sjsg }
197c349dbc7Sjsg
mock_context_reset(struct intel_context * ce)198c349dbc7Sjsg static void mock_context_reset(struct intel_context *ce)
199c349dbc7Sjsg {
200c349dbc7Sjsg }
201c349dbc7Sjsg
202c349dbc7Sjsg static const struct intel_context_ops mock_context_ops = {
203c349dbc7Sjsg .alloc = mock_context_alloc,
204c349dbc7Sjsg
205ad8b1aafSjsg .pre_pin = mock_context_pre_pin,
206c349dbc7Sjsg .pin = mock_context_pin,
207c349dbc7Sjsg .unpin = mock_context_unpin,
208ad8b1aafSjsg .post_unpin = mock_context_post_unpin,
209c349dbc7Sjsg
210c349dbc7Sjsg .enter = intel_context_enter_engine,
211c349dbc7Sjsg .exit = intel_context_exit_engine,
212c349dbc7Sjsg
213c349dbc7Sjsg .reset = mock_context_reset,
214c349dbc7Sjsg .destroy = mock_context_destroy,
215c349dbc7Sjsg };
216c349dbc7Sjsg
mock_request_alloc(struct i915_request * request)217c349dbc7Sjsg static int mock_request_alloc(struct i915_request *request)
218c349dbc7Sjsg {
219c349dbc7Sjsg INIT_LIST_HEAD(&request->mock.link);
220c349dbc7Sjsg request->mock.delay = 0;
221c349dbc7Sjsg
222c349dbc7Sjsg return 0;
223c349dbc7Sjsg }
224c349dbc7Sjsg
mock_emit_flush(struct i915_request * request,unsigned int flags)225c349dbc7Sjsg static int mock_emit_flush(struct i915_request *request,
226c349dbc7Sjsg unsigned int flags)
227c349dbc7Sjsg {
228c349dbc7Sjsg return 0;
229c349dbc7Sjsg }
230c349dbc7Sjsg
mock_emit_breadcrumb(struct i915_request * request,u32 * cs)231c349dbc7Sjsg static u32 *mock_emit_breadcrumb(struct i915_request *request, u32 *cs)
232c349dbc7Sjsg {
233c349dbc7Sjsg return cs;
234c349dbc7Sjsg }
235c349dbc7Sjsg
mock_submit_request(struct i915_request * request)236c349dbc7Sjsg static void mock_submit_request(struct i915_request *request)
237c349dbc7Sjsg {
238c349dbc7Sjsg struct mock_engine *engine =
239c349dbc7Sjsg container_of(request->engine, typeof(*engine), base);
240c349dbc7Sjsg unsigned long flags;
241c349dbc7Sjsg
242c349dbc7Sjsg i915_request_submit(request);
243c349dbc7Sjsg
244c349dbc7Sjsg spin_lock_irqsave(&engine->hw_lock, flags);
245c349dbc7Sjsg list_add_tail(&request->mock.link, &engine->hw_queue);
246c349dbc7Sjsg if (list_is_first(&request->mock.link, &engine->hw_queue)) {
247c349dbc7Sjsg if (request->mock.delay)
248c349dbc7Sjsg mod_timer(&engine->hw_delay,
249c349dbc7Sjsg jiffies + request->mock.delay);
250c349dbc7Sjsg else
251c349dbc7Sjsg advance(request);
252c349dbc7Sjsg }
253c349dbc7Sjsg spin_unlock_irqrestore(&engine->hw_lock, flags);
254c349dbc7Sjsg }
255c349dbc7Sjsg
mock_add_to_engine(struct i915_request * rq)2565ca02815Sjsg static void mock_add_to_engine(struct i915_request *rq)
2575ca02815Sjsg {
2585ca02815Sjsg lockdep_assert_held(&rq->engine->sched_engine->lock);
2595ca02815Sjsg list_move_tail(&rq->sched.link, &rq->engine->sched_engine->requests);
2605ca02815Sjsg }
2615ca02815Sjsg
mock_remove_from_engine(struct i915_request * rq)2625ca02815Sjsg static void mock_remove_from_engine(struct i915_request *rq)
2635ca02815Sjsg {
2645ca02815Sjsg struct intel_engine_cs *engine, *locked;
2655ca02815Sjsg
2665ca02815Sjsg /*
2675ca02815Sjsg * Virtual engines complicate acquiring the engine timeline lock,
2685ca02815Sjsg * as their rq->engine pointer is not stable until under that
2695ca02815Sjsg * engine lock. The simple ploy we use is to take the lock then
2705ca02815Sjsg * check that the rq still belongs to the newly locked engine.
2715ca02815Sjsg */
2725ca02815Sjsg
2735ca02815Sjsg locked = READ_ONCE(rq->engine);
2745ca02815Sjsg spin_lock_irq(&locked->sched_engine->lock);
2755ca02815Sjsg while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
2765ca02815Sjsg spin_unlock(&locked->sched_engine->lock);
2775ca02815Sjsg spin_lock(&engine->sched_engine->lock);
2785ca02815Sjsg locked = engine;
2795ca02815Sjsg }
2805ca02815Sjsg list_del_init(&rq->sched.link);
2815ca02815Sjsg spin_unlock_irq(&locked->sched_engine->lock);
2825ca02815Sjsg }
2835ca02815Sjsg
mock_reset_prepare(struct intel_engine_cs * engine)284c349dbc7Sjsg static void mock_reset_prepare(struct intel_engine_cs *engine)
285c349dbc7Sjsg {
286c349dbc7Sjsg }
287c349dbc7Sjsg
mock_reset_rewind(struct intel_engine_cs * engine,bool stalled)288c349dbc7Sjsg static void mock_reset_rewind(struct intel_engine_cs *engine, bool stalled)
289c349dbc7Sjsg {
290c349dbc7Sjsg GEM_BUG_ON(stalled);
291c349dbc7Sjsg }
292c349dbc7Sjsg
mock_reset_cancel(struct intel_engine_cs * engine)293c349dbc7Sjsg static void mock_reset_cancel(struct intel_engine_cs *engine)
294c349dbc7Sjsg {
2955ca02815Sjsg struct mock_engine *mock =
2965ca02815Sjsg container_of(engine, typeof(*mock), base);
2975ca02815Sjsg struct i915_request *rq;
298c349dbc7Sjsg unsigned long flags;
299c349dbc7Sjsg
3005ca02815Sjsg del_timer_sync(&mock->hw_delay);
3015ca02815Sjsg
3025ca02815Sjsg spin_lock_irqsave(&engine->sched_engine->lock, flags);
303c349dbc7Sjsg
304c349dbc7Sjsg /* Mark all submitted requests as skipped. */
3055ca02815Sjsg list_for_each_entry(rq, &engine->sched_engine->requests, sched.link)
3065ca02815Sjsg i915_request_put(i915_request_mark_eio(rq));
3075ca02815Sjsg intel_engine_signal_breadcrumbs(engine);
308c349dbc7Sjsg
3095ca02815Sjsg /* Cancel and submit all pending requests. */
3105ca02815Sjsg list_for_each_entry(rq, &mock->hw_queue, mock.link) {
3115ca02815Sjsg if (i915_request_mark_eio(rq)) {
3125ca02815Sjsg __i915_request_submit(rq);
3135ca02815Sjsg i915_request_put(rq);
3145ca02815Sjsg }
3155ca02815Sjsg }
3165ca02815Sjsg INIT_LIST_HEAD(&mock->hw_queue);
3175ca02815Sjsg
3185ca02815Sjsg spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
319c349dbc7Sjsg }
320c349dbc7Sjsg
mock_reset_finish(struct intel_engine_cs * engine)321c349dbc7Sjsg static void mock_reset_finish(struct intel_engine_cs *engine)
322c349dbc7Sjsg {
323c349dbc7Sjsg }
324c349dbc7Sjsg
mock_engine_release(struct intel_engine_cs * engine)325c349dbc7Sjsg static void mock_engine_release(struct intel_engine_cs *engine)
326c349dbc7Sjsg {
327c349dbc7Sjsg struct mock_engine *mock =
328c349dbc7Sjsg container_of(engine, typeof(*mock), base);
329c349dbc7Sjsg
330c349dbc7Sjsg GEM_BUG_ON(timer_pending(&mock->hw_delay));
331c349dbc7Sjsg
3325ca02815Sjsg i915_sched_engine_put(engine->sched_engine);
3335ca02815Sjsg intel_breadcrumbs_put(engine->breadcrumbs);
334ad8b1aafSjsg
335c349dbc7Sjsg intel_context_unpin(engine->kernel_context);
336c349dbc7Sjsg intel_context_put(engine->kernel_context);
337c349dbc7Sjsg
338c349dbc7Sjsg intel_engine_fini_retire(engine);
339c349dbc7Sjsg }
340c349dbc7Sjsg
mock_engine(struct drm_i915_private * i915,const char * name,int id)341c349dbc7Sjsg struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
342c349dbc7Sjsg const char *name,
343c349dbc7Sjsg int id)
344c349dbc7Sjsg {
345c349dbc7Sjsg struct mock_engine *engine;
346c349dbc7Sjsg
347c349dbc7Sjsg GEM_BUG_ON(id >= I915_NUM_ENGINES);
348*1bb76ff1Sjsg GEM_BUG_ON(!to_gt(i915)->uncore);
349c349dbc7Sjsg
350c349dbc7Sjsg engine = kzalloc(sizeof(*engine) + PAGE_SIZE, GFP_KERNEL);
351c349dbc7Sjsg if (!engine)
352c349dbc7Sjsg return NULL;
353c349dbc7Sjsg
354c349dbc7Sjsg /* minimal engine setup for requests */
355c349dbc7Sjsg engine->base.i915 = i915;
356*1bb76ff1Sjsg engine->base.gt = to_gt(i915);
357*1bb76ff1Sjsg engine->base.uncore = to_gt(i915)->uncore;
358c349dbc7Sjsg snprintf(engine->base.name, sizeof(engine->base.name), "%s", name);
359c349dbc7Sjsg engine->base.id = id;
360c349dbc7Sjsg engine->base.mask = BIT(id);
361c349dbc7Sjsg engine->base.legacy_idx = INVALID_ENGINE;
362c349dbc7Sjsg engine->base.instance = id;
363c349dbc7Sjsg engine->base.status_page.addr = (void *)(engine + 1);
364c349dbc7Sjsg
365c349dbc7Sjsg engine->base.cops = &mock_context_ops;
366c349dbc7Sjsg engine->base.request_alloc = mock_request_alloc;
367c349dbc7Sjsg engine->base.emit_flush = mock_emit_flush;
368c349dbc7Sjsg engine->base.emit_fini_breadcrumb = mock_emit_breadcrumb;
369c349dbc7Sjsg engine->base.submit_request = mock_submit_request;
3705ca02815Sjsg engine->base.add_active_request = mock_add_to_engine;
3715ca02815Sjsg engine->base.remove_active_request = mock_remove_from_engine;
372c349dbc7Sjsg
373c349dbc7Sjsg engine->base.reset.prepare = mock_reset_prepare;
374c349dbc7Sjsg engine->base.reset.rewind = mock_reset_rewind;
375c349dbc7Sjsg engine->base.reset.cancel = mock_reset_cancel;
376c349dbc7Sjsg engine->base.reset.finish = mock_reset_finish;
377c349dbc7Sjsg
378c349dbc7Sjsg engine->base.release = mock_engine_release;
379c349dbc7Sjsg
380*1bb76ff1Sjsg to_gt(i915)->engine[id] = &engine->base;
381*1bb76ff1Sjsg to_gt(i915)->engine_class[0][id] = &engine->base;
382c349dbc7Sjsg
383c349dbc7Sjsg /* fake hw queue */
384c349dbc7Sjsg mtx_init(&engine->hw_lock, IPL_TTY);
385c349dbc7Sjsg timer_setup(&engine->hw_delay, hw_delay_complete, 0);
386c349dbc7Sjsg INIT_LIST_HEAD(&engine->hw_queue);
387c349dbc7Sjsg
388c349dbc7Sjsg intel_engine_add_user(&engine->base);
389c349dbc7Sjsg
390c349dbc7Sjsg return &engine->base;
391c349dbc7Sjsg }
392c349dbc7Sjsg
mock_engine_init(struct intel_engine_cs * engine)393c349dbc7Sjsg int mock_engine_init(struct intel_engine_cs *engine)
394c349dbc7Sjsg {
395c349dbc7Sjsg struct intel_context *ce;
396c349dbc7Sjsg
3973f069f93Sjsg INIT_LIST_HEAD(&engine->pinned_contexts_list);
3983f069f93Sjsg
3995ca02815Sjsg engine->sched_engine = i915_sched_engine_create(ENGINE_MOCK);
4005ca02815Sjsg if (!engine->sched_engine)
4015ca02815Sjsg return -ENOMEM;
4025ca02815Sjsg engine->sched_engine->private_data = engine;
4035ca02815Sjsg
404c349dbc7Sjsg intel_engine_init_execlists(engine);
405c349dbc7Sjsg intel_engine_init__pm(engine);
406c349dbc7Sjsg intel_engine_init_retire(engine);
407ad8b1aafSjsg
408ad8b1aafSjsg engine->breadcrumbs = intel_breadcrumbs_create(NULL);
409ad8b1aafSjsg if (!engine->breadcrumbs)
4105ca02815Sjsg goto err_schedule;
411c349dbc7Sjsg
412c349dbc7Sjsg ce = create_kernel_context(engine);
413c349dbc7Sjsg if (IS_ERR(ce))
414c349dbc7Sjsg goto err_breadcrumbs;
415c349dbc7Sjsg
416ad8b1aafSjsg /* We insist the kernel context is using the status_page */
417ad8b1aafSjsg engine->status_page.vma = ce->timeline->hwsp_ggtt;
418ad8b1aafSjsg
419c349dbc7Sjsg engine->kernel_context = ce;
420c349dbc7Sjsg return 0;
421c349dbc7Sjsg
422c349dbc7Sjsg err_breadcrumbs:
4235ca02815Sjsg intel_breadcrumbs_put(engine->breadcrumbs);
4245ca02815Sjsg err_schedule:
4255ca02815Sjsg i915_sched_engine_put(engine->sched_engine);
426c349dbc7Sjsg return -ENOMEM;
427c349dbc7Sjsg }
428c349dbc7Sjsg
mock_engine_flush(struct intel_engine_cs * engine)429c349dbc7Sjsg void mock_engine_flush(struct intel_engine_cs *engine)
430c349dbc7Sjsg {
431c349dbc7Sjsg struct mock_engine *mock =
432c349dbc7Sjsg container_of(engine, typeof(*mock), base);
433c349dbc7Sjsg struct i915_request *request, *rn;
434c349dbc7Sjsg
435c349dbc7Sjsg del_timer_sync(&mock->hw_delay);
436c349dbc7Sjsg
437c349dbc7Sjsg spin_lock_irq(&mock->hw_lock);
438c349dbc7Sjsg list_for_each_entry_safe(request, rn, &mock->hw_queue, mock.link)
439c349dbc7Sjsg advance(request);
440c349dbc7Sjsg spin_unlock_irq(&mock->hw_lock);
441c349dbc7Sjsg }
442c349dbc7Sjsg
mock_engine_reset(struct intel_engine_cs * engine)443c349dbc7Sjsg void mock_engine_reset(struct intel_engine_cs *engine)
444c349dbc7Sjsg {
445c349dbc7Sjsg }
446