Branch data Line data Source code
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/bitops.h> 11 : : #include <linux/lockdep.h> 12 : : #include <linux/types.h> 13 : : 14 : : #include "i915_active.h" 15 : : #include "intel_context_types.h" 16 : : #include "intel_engine_types.h" 17 : : #include "intel_ring_types.h" 18 : : #include "intel_timeline_types.h" 19 : : 20 : : #define CE_TRACE(ce, fmt, ...) do { \ 21 : : const struct intel_context *ce__ = (ce); \ 22 : : ENGINE_TRACE(ce__->engine, "context:%llx " fmt, \ 23 : : ce__->timeline->fence_context, \ 24 : : ##__VA_ARGS__); \ 25 : : } while (0) 26 : : 27 : : void intel_context_init(struct intel_context *ce, 28 : : struct intel_engine_cs *engine); 29 : : void intel_context_fini(struct intel_context *ce); 30 : : 31 : : struct intel_context * 32 : : intel_context_create(struct intel_engine_cs *engine); 33 : : 34 : : int intel_context_alloc_state(struct intel_context *ce); 35 : : 36 : : void intel_context_free(struct intel_context *ce); 37 : : 38 : : /** 39 : : * intel_context_lock_pinned - Stablises the 'pinned' status of the HW context 40 : : * @ce - the context 41 : : * 42 : : * Acquire a lock on the pinned status of the HW context, such that the context 43 : : * can neither be bound to the GPU or unbound whilst the lock is held, i.e. 44 : : * intel_context_is_pinned() remains stable. 45 : : */ 46 : 0 : static inline int intel_context_lock_pinned(struct intel_context *ce) 47 : : __acquires(ce->pin_mutex) 48 : : { 49 : 0 : return mutex_lock_interruptible(&ce->pin_mutex); 50 : : } 51 : : 52 : : /** 53 : : * intel_context_is_pinned - Reports the 'pinned' status 54 : : * @ce - the context 55 : : * 56 : : * While in use by the GPU, the context, along with its ring and page 57 : : * tables is pinned into memory and the GTT. 58 : : * 59 : : * Returns: true if the context is currently pinned for use by the GPU. 60 : : */ 61 : : static inline bool 62 : : intel_context_is_pinned(struct intel_context *ce) 63 : : { 64 : : return atomic_read(&ce->pin_count); 65 : : } 66 : : 67 : : /** 68 : : * intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status 69 : : * @ce - the context 70 : : * 71 : : * Releases the lock earlier acquired by intel_context_unlock_pinned(). 72 : : */ 73 : 0 : static inline void intel_context_unlock_pinned(struct intel_context *ce) 74 : : __releases(ce->pin_mutex) 75 : : { 76 : 0 : mutex_unlock(&ce->pin_mutex); 77 : : } 78 : : 79 : : int __intel_context_do_pin(struct intel_context *ce); 80 : : 81 : 0 : static inline bool intel_context_pin_if_active(struct intel_context *ce) 82 : : { 83 : 0 : return atomic_inc_not_zero(&ce->pin_count); 84 : : } 85 : : 86 : 0 : static inline int intel_context_pin(struct intel_context *ce) 87 : : { 88 [ # # ]: 0 : if (likely(intel_context_pin_if_active(ce))) 89 : : return 0; 90 : : 91 : 0 : return __intel_context_do_pin(ce); 92 : : } 93 : : 94 : 0 : static inline void __intel_context_pin(struct intel_context *ce) 95 : : { 96 : 0 : GEM_BUG_ON(!intel_context_is_pinned(ce)); 97 : 0 : atomic_inc(&ce->pin_count); 98 : : } 99 : : 100 : : void intel_context_unpin(struct intel_context *ce); 101 : : 102 : : void intel_context_enter_engine(struct intel_context *ce); 103 : : void intel_context_exit_engine(struct intel_context *ce); 104 : : 105 : 0 : static inline void intel_context_enter(struct intel_context *ce) 106 : : { 107 : 0 : lockdep_assert_held(&ce->timeline->mutex); 108 [ # # # # ]: 0 : if (!ce->active_count++) 109 : 0 : ce->ops->enter(ce); 110 : : } 111 : : 112 : 0 : static inline void intel_context_mark_active(struct intel_context *ce) 113 : : { 114 : 0 : lockdep_assert_held(&ce->timeline->mutex); 115 : 0 : ++ce->active_count; 116 : : } 117 : : 118 : 0 : static inline void intel_context_exit(struct intel_context *ce) 119 : : { 120 : 0 : lockdep_assert_held(&ce->timeline->mutex); 121 : 0 : GEM_BUG_ON(!ce->active_count); 122 [ # # # # ]: 0 : if (!--ce->active_count) 123 : 0 : ce->ops->exit(ce); 124 : : } 125 : : 126 : 0 : static inline struct intel_context *intel_context_get(struct intel_context *ce) 127 : : { 128 : 0 : kref_get(&ce->ref); 129 : 0 : return ce; 130 : : } 131 : : 132 : 0 : static inline void intel_context_put(struct intel_context *ce) 133 : : { 134 : 0 : kref_put(&ce->ref, ce->ops->destroy); 135 : 0 : } 136 : : 137 : : static inline struct intel_timeline *__must_check 138 : 0 : intel_context_timeline_lock(struct intel_context *ce) 139 : : __acquires(&ce->timeline->mutex) 140 : : { 141 : 0 : struct intel_timeline *tl = ce->timeline; 142 : 0 : int err; 143 : : 144 : 0 : err = mutex_lock_interruptible(&tl->mutex); 145 [ # # ]: 0 : if (err) 146 : 0 : return ERR_PTR(err); 147 : : 148 : : return tl; 149 : : } 150 : : 151 : 0 : static inline void intel_context_timeline_unlock(struct intel_timeline *tl) 152 : : __releases(&tl->mutex) 153 : : { 154 : 0 : mutex_unlock(&tl->mutex); 155 : : } 156 : : 157 : : int intel_context_prepare_remote_request(struct intel_context *ce, 158 : : struct i915_request *rq); 159 : : 160 : : struct i915_request *intel_context_create_request(struct intel_context *ce); 161 : : 162 : 0 : static inline struct intel_ring *__intel_context_ring_size(u64 sz) 163 : : { 164 : 0 : return u64_to_ptr(struct intel_ring, sz); 165 : : } 166 : : 167 : 0 : static inline bool intel_context_is_barrier(const struct intel_context *ce) 168 : : { 169 : 0 : return test_bit(CONTEXT_BARRIER_BIT, &ce->flags); 170 : : } 171 : : 172 : 0 : static inline bool intel_context_use_semaphores(const struct intel_context *ce) 173 : : { 174 : 0 : return test_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 175 : : } 176 : : 177 : 0 : static inline void intel_context_set_use_semaphores(struct intel_context *ce) 178 : : { 179 : 0 : set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 180 : 0 : } 181 : : 182 : 0 : static inline void intel_context_clear_use_semaphores(struct intel_context *ce) 183 : : { 184 : 0 : clear_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 185 : 0 : } 186 : : 187 : 0 : static inline bool intel_context_is_banned(const struct intel_context *ce) 188 : : { 189 : 0 : return test_bit(CONTEXT_BANNED, &ce->flags); 190 : : } 191 : : 192 : 0 : static inline bool intel_context_set_banned(struct intel_context *ce) 193 : : { 194 : 0 : return test_and_set_bit(CONTEXT_BANNED, &ce->flags); 195 : : } 196 : : 197 : : static inline bool 198 : : intel_context_force_single_submission(const struct intel_context *ce) 199 : : { 200 : : return test_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ce->flags); 201 : : } 202 : : 203 : : static inline void 204 : : intel_context_set_single_submission(struct intel_context *ce) 205 : : { 206 : : __set_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ce->flags); 207 : : } 208 : : 209 : : static inline bool 210 : 0 : intel_context_nopreempt(const struct intel_context *ce) 211 : : { 212 : 0 : return test_bit(CONTEXT_NOPREEMPT, &ce->flags); 213 : : } 214 : : 215 : : static inline void 216 : 0 : intel_context_set_nopreempt(struct intel_context *ce) 217 : : { 218 : 0 : set_bit(CONTEXT_NOPREEMPT, &ce->flags); 219 : 0 : } 220 : : 221 : : static inline void 222 : 0 : intel_context_clear_nopreempt(struct intel_context *ce) 223 : : { 224 : 0 : clear_bit(CONTEXT_NOPREEMPT, &ce->flags); 225 : 0 : } 226 : : 227 : : #endif /* __INTEL_CONTEXT_H__ */