1 /*
2  * SPDX-License-Identifier: MIT
3  *
4  * Copyright © 2019 Intel Corporation
5  */
6 
7 #ifndef __INTEL_CONTEXT_H__
8 #define __INTEL_CONTEXT_H__
9 
10 #include <linux/lockdep.h>
11 
12 #include "i915_active.h"
13 #include "intel_context_types.h"
14 #include "intel_engine_types.h"
15 
16 void intel_context_init(struct intel_context *ce,
17 			struct i915_gem_context *ctx,
18 			struct intel_engine_cs *engine);
19 void intel_context_fini(struct intel_context *ce);
20 
21 struct intel_context *
22 intel_context_create(struct i915_gem_context *ctx,
23 		     struct intel_engine_cs *engine);
24 
25 void intel_context_free(struct intel_context *ce);
26 
27 /**
28  * intel_context_lock_pinned - Stablises the 'pinned' status of the HW context
29  * @ce - the context
30  *
31  * Acquire a lock on the pinned status of the HW context, such that the context
32  * can neither be bound to the GPU or unbound whilst the lock is held, i.e.
33  * intel_context_is_pinned() remains stable.
34  */
35 static inline int intel_context_lock_pinned(struct intel_context *ce)
36 	__acquires(ce->pin_mutex)
37 {
38 	return mutex_lock_interruptible(&ce->pin_mutex);
39 }
40 
41 /**
42  * intel_context_is_pinned - Reports the 'pinned' status
43  * @ce - the context
44  *
45  * While in use by the GPU, the context, along with its ring and page
46  * tables is pinned into memory and the GTT.
47  *
48  * Returns: true if the context is currently pinned for use by the GPU.
49  */
50 static inline bool
51 intel_context_is_pinned(struct intel_context *ce)
52 {
53 	return atomic_read(&ce->pin_count);
54 }
55 
56 /**
57  * intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status
58  * @ce - the context
59  *
60  * Releases the lock earlier acquired by intel_context_unlock_pinned().
61  */
62 static inline void intel_context_unlock_pinned(struct intel_context *ce)
63 	__releases(ce->pin_mutex)
64 {
65 	mutex_unlock(&ce->pin_mutex);
66 }
67 
68 int __intel_context_do_pin(struct intel_context *ce);
69 
70 static inline int intel_context_pin(struct intel_context *ce)
71 {
72 	if (likely(atomic_inc_not_zero(&ce->pin_count)))
73 		return 0;
74 
75 	return __intel_context_do_pin(ce);
76 }
77 
78 static inline void __intel_context_pin(struct intel_context *ce)
79 {
80 	GEM_BUG_ON(!intel_context_is_pinned(ce));
81 	atomic_inc(&ce->pin_count);
82 }
83 
84 void intel_context_unpin(struct intel_context *ce);
85 
86 void intel_context_enter_engine(struct intel_context *ce);
87 void intel_context_exit_engine(struct intel_context *ce);
88 
89 static inline void intel_context_enter(struct intel_context *ce)
90 {
91 	if (!ce->active_count++)
92 		ce->ops->enter(ce);
93 }
94 
95 static inline void intel_context_mark_active(struct intel_context *ce)
96 {
97 	++ce->active_count;
98 }
99 
100 static inline void intel_context_exit(struct intel_context *ce)
101 {
102 	GEM_BUG_ON(!ce->active_count);
103 	if (!--ce->active_count)
104 		ce->ops->exit(ce);
105 }
106 
107 static inline int intel_context_active_acquire(struct intel_context *ce)
108 {
109 	return i915_active_acquire(&ce->active);
110 }
111 
112 static inline void intel_context_active_release(struct intel_context *ce)
113 {
114 	/* Nodes preallocated in intel_context_active() */
115 	i915_active_acquire_barrier(&ce->active);
116 	i915_active_release(&ce->active);
117 }
118 
119 static inline struct intel_context *intel_context_get(struct intel_context *ce)
120 {
121 	kref_get(&ce->ref);
122 	return ce;
123 }
124 
125 static inline void intel_context_put(struct intel_context *ce)
126 {
127 	kref_put(&ce->ref, ce->ops->destroy);
128 }
129 
130 static inline int __must_check
131 intel_context_timeline_lock(struct intel_context *ce)
132 	__acquires(&ce->ring->timeline->mutex)
133 {
134 	return mutex_lock_interruptible(&ce->ring->timeline->mutex);
135 }
136 
137 static inline void intel_context_timeline_unlock(struct intel_context *ce)
138 	__releases(&ce->ring->timeline->mutex)
139 {
140 	mutex_unlock(&ce->ring->timeline->mutex);
141 }
142 
143 int intel_context_prepare_remote_request(struct intel_context *ce,
144 					 struct i915_request *rq);
145 
146 struct i915_request *intel_context_create_request(struct intel_context *ce);
147 
148 #endif /* __INTEL_CONTEXT_H__ */
149