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