xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/i915/gt/intel_context.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * SPDX-License-Identifier: MIT
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright © 2019 Intel Corporation
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include "gem/i915_gem_context.h"
8*4882a593Smuzhiyun #include "gem/i915_gem_pm.h"
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "i915_drv.h"
11*4882a593Smuzhiyun #include "i915_globals.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "intel_context.h"
14*4882a593Smuzhiyun #include "intel_engine.h"
15*4882a593Smuzhiyun #include "intel_engine_pm.h"
16*4882a593Smuzhiyun #include "intel_ring.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun static struct i915_global_context {
19*4882a593Smuzhiyun 	struct i915_global base;
20*4882a593Smuzhiyun 	struct kmem_cache *slab_ce;
21*4882a593Smuzhiyun } global;
22*4882a593Smuzhiyun 
intel_context_alloc(void)23*4882a593Smuzhiyun static struct intel_context *intel_context_alloc(void)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	return kmem_cache_zalloc(global.slab_ce, GFP_KERNEL);
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun 
rcu_context_free(struct rcu_head * rcu)28*4882a593Smuzhiyun static void rcu_context_free(struct rcu_head *rcu)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	struct intel_context *ce = container_of(rcu, typeof(*ce), rcu);
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	kmem_cache_free(global.slab_ce, ce);
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
intel_context_free(struct intel_context * ce)35*4882a593Smuzhiyun void intel_context_free(struct intel_context *ce)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	call_rcu(&ce->rcu, rcu_context_free);
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun struct intel_context *
intel_context_create(struct intel_engine_cs * engine)41*4882a593Smuzhiyun intel_context_create(struct intel_engine_cs *engine)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	struct intel_context *ce;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	ce = intel_context_alloc();
46*4882a593Smuzhiyun 	if (!ce)
47*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	intel_context_init(ce, engine);
50*4882a593Smuzhiyun 	return ce;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
intel_context_alloc_state(struct intel_context * ce)53*4882a593Smuzhiyun int intel_context_alloc_state(struct intel_context *ce)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	int err = 0;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	if (mutex_lock_interruptible(&ce->pin_mutex))
58*4882a593Smuzhiyun 		return -EINTR;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
61*4882a593Smuzhiyun 		if (intel_context_is_banned(ce)) {
62*4882a593Smuzhiyun 			err = -EIO;
63*4882a593Smuzhiyun 			goto unlock;
64*4882a593Smuzhiyun 		}
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 		err = ce->ops->alloc(ce);
67*4882a593Smuzhiyun 		if (unlikely(err))
68*4882a593Smuzhiyun 			goto unlock;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 		set_bit(CONTEXT_ALLOC_BIT, &ce->flags);
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun unlock:
74*4882a593Smuzhiyun 	mutex_unlock(&ce->pin_mutex);
75*4882a593Smuzhiyun 	return err;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
intel_context_active_acquire(struct intel_context * ce)78*4882a593Smuzhiyun static int intel_context_active_acquire(struct intel_context *ce)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	int err;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	__i915_active_acquire(&ce->active);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	if (intel_context_is_barrier(ce))
85*4882a593Smuzhiyun 		return 0;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Preallocate tracking nodes */
88*4882a593Smuzhiyun 	err = i915_active_acquire_preallocate_barrier(&ce->active,
89*4882a593Smuzhiyun 						      ce->engine);
90*4882a593Smuzhiyun 	if (err)
91*4882a593Smuzhiyun 		i915_active_release(&ce->active);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	return err;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
intel_context_active_release(struct intel_context * ce)96*4882a593Smuzhiyun static void intel_context_active_release(struct intel_context *ce)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	/* Nodes preallocated in intel_context_active() */
99*4882a593Smuzhiyun 	i915_active_acquire_barrier(&ce->active);
100*4882a593Smuzhiyun 	i915_active_release(&ce->active);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
__context_pin_state(struct i915_vma * vma,struct i915_gem_ww_ctx * ww)103*4882a593Smuzhiyun static int __context_pin_state(struct i915_vma *vma, struct i915_gem_ww_ctx *ww)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	unsigned int bias = i915_ggtt_pin_bias(vma) | PIN_OFFSET_BIAS;
106*4882a593Smuzhiyun 	int err;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	err = i915_ggtt_pin(vma, ww, 0, bias | PIN_HIGH);
109*4882a593Smuzhiyun 	if (err)
110*4882a593Smuzhiyun 		return err;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	err = i915_active_acquire(&vma->active);
113*4882a593Smuzhiyun 	if (err)
114*4882a593Smuzhiyun 		goto err_unpin;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/*
117*4882a593Smuzhiyun 	 * And mark it as a globally pinned object to let the shrinker know
118*4882a593Smuzhiyun 	 * it cannot reclaim the object until we release it.
119*4882a593Smuzhiyun 	 */
120*4882a593Smuzhiyun 	i915_vma_make_unshrinkable(vma);
121*4882a593Smuzhiyun 	vma->obj->mm.dirty = true;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	return 0;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun err_unpin:
126*4882a593Smuzhiyun 	i915_vma_unpin(vma);
127*4882a593Smuzhiyun 	return err;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
__context_unpin_state(struct i915_vma * vma)130*4882a593Smuzhiyun static void __context_unpin_state(struct i915_vma *vma)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	i915_vma_make_shrinkable(vma);
133*4882a593Smuzhiyun 	i915_active_release(&vma->active);
134*4882a593Smuzhiyun 	__i915_vma_unpin(vma);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
__ring_active(struct intel_ring * ring,struct i915_gem_ww_ctx * ww)137*4882a593Smuzhiyun static int __ring_active(struct intel_ring *ring,
138*4882a593Smuzhiyun 			 struct i915_gem_ww_ctx *ww)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	int err;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	err = intel_ring_pin(ring, ww);
143*4882a593Smuzhiyun 	if (err)
144*4882a593Smuzhiyun 		return err;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	err = i915_active_acquire(&ring->vma->active);
147*4882a593Smuzhiyun 	if (err)
148*4882a593Smuzhiyun 		goto err_pin;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	return 0;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun err_pin:
153*4882a593Smuzhiyun 	intel_ring_unpin(ring);
154*4882a593Smuzhiyun 	return err;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
__ring_retire(struct intel_ring * ring)157*4882a593Smuzhiyun static void __ring_retire(struct intel_ring *ring)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	i915_active_release(&ring->vma->active);
160*4882a593Smuzhiyun 	intel_ring_unpin(ring);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
intel_context_pre_pin(struct intel_context * ce,struct i915_gem_ww_ctx * ww)163*4882a593Smuzhiyun static int intel_context_pre_pin(struct intel_context *ce,
164*4882a593Smuzhiyun 				 struct i915_gem_ww_ctx *ww)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	int err;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	CE_TRACE(ce, "active\n");
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	err = __ring_active(ce->ring, ww);
171*4882a593Smuzhiyun 	if (err)
172*4882a593Smuzhiyun 		return err;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	err = intel_timeline_pin(ce->timeline, ww);
175*4882a593Smuzhiyun 	if (err)
176*4882a593Smuzhiyun 		goto err_ring;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	if (!ce->state)
179*4882a593Smuzhiyun 		return 0;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	err = __context_pin_state(ce->state, ww);
182*4882a593Smuzhiyun 	if (err)
183*4882a593Smuzhiyun 		goto err_timeline;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	return 0;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun err_timeline:
189*4882a593Smuzhiyun 	intel_timeline_unpin(ce->timeline);
190*4882a593Smuzhiyun err_ring:
191*4882a593Smuzhiyun 	__ring_retire(ce->ring);
192*4882a593Smuzhiyun 	return err;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
intel_context_post_unpin(struct intel_context * ce)195*4882a593Smuzhiyun static void intel_context_post_unpin(struct intel_context *ce)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	if (ce->state)
198*4882a593Smuzhiyun 		__context_unpin_state(ce->state);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	intel_timeline_unpin(ce->timeline);
201*4882a593Smuzhiyun 	__ring_retire(ce->ring);
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
__intel_context_do_pin_ww(struct intel_context * ce,struct i915_gem_ww_ctx * ww)204*4882a593Smuzhiyun int __intel_context_do_pin_ww(struct intel_context *ce,
205*4882a593Smuzhiyun 			      struct i915_gem_ww_ctx *ww)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	bool handoff = false;
208*4882a593Smuzhiyun 	void *vaddr;
209*4882a593Smuzhiyun 	int err = 0;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
212*4882a593Smuzhiyun 		err = intel_context_alloc_state(ce);
213*4882a593Smuzhiyun 		if (err)
214*4882a593Smuzhiyun 			return err;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	/*
218*4882a593Smuzhiyun 	 * We always pin the context/ring/timeline here, to ensure a pin
219*4882a593Smuzhiyun 	 * refcount for __intel_context_active(), which prevent a lock
220*4882a593Smuzhiyun 	 * inversion of ce->pin_mutex vs dma_resv_lock().
221*4882a593Smuzhiyun 	 */
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
224*4882a593Smuzhiyun 	if (!err && ce->ring->vma->obj)
225*4882a593Smuzhiyun 		err = i915_gem_object_lock(ce->ring->vma->obj, ww);
226*4882a593Smuzhiyun 	if (!err && ce->state)
227*4882a593Smuzhiyun 		err = i915_gem_object_lock(ce->state->obj, ww);
228*4882a593Smuzhiyun 	if (!err)
229*4882a593Smuzhiyun 		err = intel_context_pre_pin(ce, ww);
230*4882a593Smuzhiyun 	if (err)
231*4882a593Smuzhiyun 		return err;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	err = i915_active_acquire(&ce->active);
234*4882a593Smuzhiyun 	if (err)
235*4882a593Smuzhiyun 		goto err_ctx_unpin;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	err = ce->ops->pre_pin(ce, ww, &vaddr);
238*4882a593Smuzhiyun 	if (err)
239*4882a593Smuzhiyun 		goto err_release;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	err = mutex_lock_interruptible(&ce->pin_mutex);
242*4882a593Smuzhiyun 	if (err)
243*4882a593Smuzhiyun 		goto err_post_unpin;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (unlikely(intel_context_is_closed(ce))) {
246*4882a593Smuzhiyun 		err = -ENOENT;
247*4882a593Smuzhiyun 		goto err_unlock;
248*4882a593Smuzhiyun 	}
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) {
251*4882a593Smuzhiyun 		err = intel_context_active_acquire(ce);
252*4882a593Smuzhiyun 		if (unlikely(err))
253*4882a593Smuzhiyun 			goto err_unlock;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 		err = ce->ops->pin(ce, vaddr);
256*4882a593Smuzhiyun 		if (err) {
257*4882a593Smuzhiyun 			intel_context_active_release(ce);
258*4882a593Smuzhiyun 			goto err_unlock;
259*4882a593Smuzhiyun 		}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 		CE_TRACE(ce, "pin ring:{start:%08x, head:%04x, tail:%04x}\n",
262*4882a593Smuzhiyun 			 i915_ggtt_offset(ce->ring->vma),
263*4882a593Smuzhiyun 			 ce->ring->head, ce->ring->tail);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 		handoff = true;
266*4882a593Smuzhiyun 		smp_mb__before_atomic(); /* flush pin before it is visible */
267*4882a593Smuzhiyun 		atomic_inc(&ce->pin_count);
268*4882a593Smuzhiyun 	}
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun err_unlock:
273*4882a593Smuzhiyun 	mutex_unlock(&ce->pin_mutex);
274*4882a593Smuzhiyun err_post_unpin:
275*4882a593Smuzhiyun 	if (!handoff)
276*4882a593Smuzhiyun 		ce->ops->post_unpin(ce);
277*4882a593Smuzhiyun err_release:
278*4882a593Smuzhiyun 	i915_active_release(&ce->active);
279*4882a593Smuzhiyun err_ctx_unpin:
280*4882a593Smuzhiyun 	intel_context_post_unpin(ce);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	/*
283*4882a593Smuzhiyun 	 * Unlock the hwsp_ggtt object since it's shared.
284*4882a593Smuzhiyun 	 * In principle we can unlock all the global state locked above
285*4882a593Smuzhiyun 	 * since it's pinned and doesn't need fencing, and will
286*4882a593Smuzhiyun 	 * thus remain resident until it is explicitly unpinned.
287*4882a593Smuzhiyun 	 */
288*4882a593Smuzhiyun 	i915_gem_ww_unlock_single(ce->timeline->hwsp_ggtt->obj);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	return err;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
__intel_context_do_pin(struct intel_context * ce)293*4882a593Smuzhiyun int __intel_context_do_pin(struct intel_context *ce)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	struct i915_gem_ww_ctx ww;
296*4882a593Smuzhiyun 	int err;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	i915_gem_ww_ctx_init(&ww, true);
299*4882a593Smuzhiyun retry:
300*4882a593Smuzhiyun 	err = __intel_context_do_pin_ww(ce, &ww);
301*4882a593Smuzhiyun 	if (err == -EDEADLK) {
302*4882a593Smuzhiyun 		err = i915_gem_ww_ctx_backoff(&ww);
303*4882a593Smuzhiyun 		if (!err)
304*4882a593Smuzhiyun 			goto retry;
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun 	i915_gem_ww_ctx_fini(&ww);
307*4882a593Smuzhiyun 	return err;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
intel_context_unpin(struct intel_context * ce)310*4882a593Smuzhiyun void intel_context_unpin(struct intel_context *ce)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	if (!atomic_dec_and_test(&ce->pin_count))
313*4882a593Smuzhiyun 		return;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	CE_TRACE(ce, "unpin\n");
316*4882a593Smuzhiyun 	ce->ops->unpin(ce);
317*4882a593Smuzhiyun 	ce->ops->post_unpin(ce);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	/*
320*4882a593Smuzhiyun 	 * Once released, we may asynchronously drop the active reference.
321*4882a593Smuzhiyun 	 * As that may be the only reference keeping the context alive,
322*4882a593Smuzhiyun 	 * take an extra now so that it is not freed before we finish
323*4882a593Smuzhiyun 	 * dereferencing it.
324*4882a593Smuzhiyun 	 */
325*4882a593Smuzhiyun 	intel_context_get(ce);
326*4882a593Smuzhiyun 	intel_context_active_release(ce);
327*4882a593Smuzhiyun 	intel_context_put(ce);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun __i915_active_call
__intel_context_retire(struct i915_active * active)331*4882a593Smuzhiyun static void __intel_context_retire(struct i915_active *active)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun 	struct intel_context *ce = container_of(active, typeof(*ce), active);
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
336*4882a593Smuzhiyun 		 intel_context_get_total_runtime_ns(ce),
337*4882a593Smuzhiyun 		 intel_context_get_avg_runtime_ns(ce));
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	set_bit(CONTEXT_VALID_BIT, &ce->flags);
340*4882a593Smuzhiyun 	intel_context_post_unpin(ce);
341*4882a593Smuzhiyun 	intel_context_put(ce);
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
__intel_context_active(struct i915_active * active)344*4882a593Smuzhiyun static int __intel_context_active(struct i915_active *active)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	struct intel_context *ce = container_of(active, typeof(*ce), active);
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	intel_context_get(ce);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	/* everything should already be activated by intel_context_pre_pin() */
351*4882a593Smuzhiyun 	GEM_WARN_ON(!i915_active_acquire_if_busy(&ce->ring->vma->active));
352*4882a593Smuzhiyun 	__intel_ring_pin(ce->ring);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	__intel_timeline_pin(ce->timeline);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (ce->state) {
357*4882a593Smuzhiyun 		GEM_WARN_ON(!i915_active_acquire_if_busy(&ce->state->active));
358*4882a593Smuzhiyun 		__i915_vma_pin(ce->state);
359*4882a593Smuzhiyun 		i915_vma_make_unshrinkable(ce->state);
360*4882a593Smuzhiyun 	}
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	return 0;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun void
intel_context_init(struct intel_context * ce,struct intel_engine_cs * engine)366*4882a593Smuzhiyun intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun 	GEM_BUG_ON(!engine->cops);
369*4882a593Smuzhiyun 	GEM_BUG_ON(!engine->gt->vm);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	kref_init(&ce->ref);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	ce->engine = engine;
374*4882a593Smuzhiyun 	ce->ops = engine->cops;
375*4882a593Smuzhiyun 	ce->sseu = engine->sseu;
376*4882a593Smuzhiyun 	ce->ring = __intel_context_ring_size(SZ_4K);
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	ewma_runtime_init(&ce->runtime.avg);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	ce->vm = i915_vm_get(engine->gt->vm);
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	/* NB ce->signal_link/lock is used under RCU */
383*4882a593Smuzhiyun 	spin_lock_init(&ce->signal_lock);
384*4882a593Smuzhiyun 	INIT_LIST_HEAD(&ce->signals);
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	mutex_init(&ce->pin_mutex);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	i915_active_init(&ce->active,
389*4882a593Smuzhiyun 			 __intel_context_active, __intel_context_retire);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun 
intel_context_fini(struct intel_context * ce)392*4882a593Smuzhiyun void intel_context_fini(struct intel_context *ce)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun 	if (ce->timeline)
395*4882a593Smuzhiyun 		intel_timeline_put(ce->timeline);
396*4882a593Smuzhiyun 	i915_vm_put(ce->vm);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	mutex_destroy(&ce->pin_mutex);
399*4882a593Smuzhiyun 	i915_active_fini(&ce->active);
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
i915_global_context_shrink(void)402*4882a593Smuzhiyun static void i915_global_context_shrink(void)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 	kmem_cache_shrink(global.slab_ce);
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun 
i915_global_context_exit(void)407*4882a593Smuzhiyun static void i915_global_context_exit(void)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	kmem_cache_destroy(global.slab_ce);
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun static struct i915_global_context global = { {
413*4882a593Smuzhiyun 	.shrink = i915_global_context_shrink,
414*4882a593Smuzhiyun 	.exit = i915_global_context_exit,
415*4882a593Smuzhiyun } };
416*4882a593Smuzhiyun 
i915_global_context_init(void)417*4882a593Smuzhiyun int __init i915_global_context_init(void)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	global.slab_ce = KMEM_CACHE(intel_context, SLAB_HWCACHE_ALIGN);
420*4882a593Smuzhiyun 	if (!global.slab_ce)
421*4882a593Smuzhiyun 		return -ENOMEM;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	i915_global_register(&global.base);
424*4882a593Smuzhiyun 	return 0;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
intel_context_enter_engine(struct intel_context * ce)427*4882a593Smuzhiyun void intel_context_enter_engine(struct intel_context *ce)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun 	intel_engine_pm_get(ce->engine);
430*4882a593Smuzhiyun 	intel_timeline_enter(ce->timeline);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
intel_context_exit_engine(struct intel_context * ce)433*4882a593Smuzhiyun void intel_context_exit_engine(struct intel_context *ce)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun 	intel_timeline_exit(ce->timeline);
436*4882a593Smuzhiyun 	intel_engine_pm_put(ce->engine);
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun 
intel_context_prepare_remote_request(struct intel_context * ce,struct i915_request * rq)439*4882a593Smuzhiyun int intel_context_prepare_remote_request(struct intel_context *ce,
440*4882a593Smuzhiyun 					 struct i915_request *rq)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun 	struct intel_timeline *tl = ce->timeline;
443*4882a593Smuzhiyun 	int err;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	/* Only suitable for use in remotely modifying this context */
446*4882a593Smuzhiyun 	GEM_BUG_ON(rq->context == ce);
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	if (rcu_access_pointer(rq->timeline) != tl) { /* timeline sharing! */
449*4882a593Smuzhiyun 		/* Queue this switch after current activity by this context. */
450*4882a593Smuzhiyun 		err = i915_active_fence_set(&tl->last_request, rq);
451*4882a593Smuzhiyun 		if (err)
452*4882a593Smuzhiyun 			return err;
453*4882a593Smuzhiyun 	}
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	/*
456*4882a593Smuzhiyun 	 * Guarantee context image and the timeline remains pinned until the
457*4882a593Smuzhiyun 	 * modifying request is retired by setting the ce activity tracker.
458*4882a593Smuzhiyun 	 *
459*4882a593Smuzhiyun 	 * But we only need to take one pin on the account of it. Or in other
460*4882a593Smuzhiyun 	 * words transfer the pinned ce object to tracked active request.
461*4882a593Smuzhiyun 	 */
462*4882a593Smuzhiyun 	GEM_BUG_ON(i915_active_is_idle(&ce->active));
463*4882a593Smuzhiyun 	return i915_active_add_request(&ce->active, rq);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
intel_context_create_request(struct intel_context * ce)466*4882a593Smuzhiyun struct i915_request *intel_context_create_request(struct intel_context *ce)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	struct i915_gem_ww_ctx ww;
469*4882a593Smuzhiyun 	struct i915_request *rq;
470*4882a593Smuzhiyun 	int err;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	i915_gem_ww_ctx_init(&ww, true);
473*4882a593Smuzhiyun retry:
474*4882a593Smuzhiyun 	err = intel_context_pin_ww(ce, &ww);
475*4882a593Smuzhiyun 	if (!err) {
476*4882a593Smuzhiyun 		rq = i915_request_create(ce);
477*4882a593Smuzhiyun 		intel_context_unpin(ce);
478*4882a593Smuzhiyun 	} else if (err == -EDEADLK) {
479*4882a593Smuzhiyun 		err = i915_gem_ww_ctx_backoff(&ww);
480*4882a593Smuzhiyun 		if (!err)
481*4882a593Smuzhiyun 			goto retry;
482*4882a593Smuzhiyun 		rq = ERR_PTR(err);
483*4882a593Smuzhiyun 	} else {
484*4882a593Smuzhiyun 		rq = ERR_PTR(err);
485*4882a593Smuzhiyun 	}
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	i915_gem_ww_ctx_fini(&ww);
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	if (IS_ERR(rq))
490*4882a593Smuzhiyun 		return rq;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	/*
493*4882a593Smuzhiyun 	 * timeline->mutex should be the inner lock, but is used as outer lock.
494*4882a593Smuzhiyun 	 * Hack around this to shut up lockdep in selftests..
495*4882a593Smuzhiyun 	 */
496*4882a593Smuzhiyun 	lockdep_unpin_lock(&ce->timeline->mutex, rq->cookie);
497*4882a593Smuzhiyun 	mutex_release(&ce->timeline->mutex.dep_map, _RET_IP_);
498*4882a593Smuzhiyun 	mutex_acquire(&ce->timeline->mutex.dep_map, SINGLE_DEPTH_NESTING, 0, _RET_IP_);
499*4882a593Smuzhiyun 	rq->cookie = lockdep_pin_lock(&ce->timeline->mutex);
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	return rq;
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
505*4882a593Smuzhiyun #include "selftest_context.c"
506*4882a593Smuzhiyun #endif
507