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