i915_gem_request.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright © 2008-2015 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. */
  24. #ifndef I915_GEM_REQUEST_H
  25. #define I915_GEM_REQUEST_H
  26. /**
  27. * Request queue structure.
  28. *
  29. * The request queue allows us to note sequence numbers that have been emitted
  30. * and may be associated with active buffers to be retired.
  31. *
  32. * By keeping this list, we can avoid having to do questionable sequence
  33. * number comparisons on buffer last_read|write_seqno. It also allows an
  34. * emission time to be associated with the request for tracking how far ahead
  35. * of the GPU the submission is.
  36. *
  37. * The requests are reference counted, so upon creation they should have an
  38. * initial reference taken using kref_init
  39. */
  40. struct drm_i915_gem_request {
  41. struct kref ref;
  42. /** On Which ring this request was generated */
  43. struct drm_i915_private *i915;
  44. /**
  45. * Context and ring buffer related to this request
  46. * Contexts are refcounted, so when this request is associated with a
  47. * context, we must increment the context's refcount, to guarantee that
  48. * it persists while any request is linked to it. Requests themselves
  49. * are also refcounted, so the request will only be freed when the last
  50. * reference to it is dismissed, and the code in
  51. * i915_gem_request_free() will then decrement the refcount on the
  52. * context.
  53. */
  54. struct i915_gem_context *ctx;
  55. struct intel_engine_cs *engine;
  56. struct intel_ringbuffer *ringbuf;
  57. struct intel_signal_node signaling;
  58. /** GEM sequence number associated with the previous request,
  59. * when the HWS breadcrumb is equal to this the GPU is processing
  60. * this request.
  61. */
  62. u32 previous_seqno;
  63. /** GEM sequence number associated with this request,
  64. * when the HWS breadcrumb is equal or greater than this the GPU
  65. * has finished processing this request.
  66. */
  67. u32 seqno;
  68. /** Position in the ringbuffer of the start of the request */
  69. u32 head;
  70. /**
  71. * Position in the ringbuffer of the start of the postfix.
  72. * This is required to calculate the maximum available ringbuffer
  73. * space without overwriting the postfix.
  74. */
  75. u32 postfix;
  76. /** Position in the ringbuffer of the end of the whole request */
  77. u32 tail;
  78. /** Preallocate space in the ringbuffer for the emitting the request */
  79. u32 reserved_space;
  80. /**
  81. * Context related to the previous request.
  82. * As the contexts are accessed by the hardware until the switch is
  83. * completed to a new context, the hardware may still be writing
  84. * to the context object after the breadcrumb is visible. We must
  85. * not unpin/unbind/prune that object whilst still active and so
  86. * we keep the previous context pinned until the following (this)
  87. * request is retired.
  88. */
  89. struct i915_gem_context *previous_context;
  90. /** Batch buffer related to this request if any (used for
  91. * error state dump only).
  92. */
  93. struct drm_i915_gem_object *batch_obj;
  94. /** Time at which this request was emitted, in jiffies. */
  95. unsigned long emitted_jiffies;
  96. /** global list entry for this request */
  97. struct list_head list;
  98. struct drm_i915_file_private *file_priv;
  99. /** file_priv list entry for this request */
  100. struct list_head client_list;
  101. /** process identifier submitting this request */
  102. struct pid *pid;
  103. /**
  104. * The ELSP only accepts two elements at a time, so we queue
  105. * context/tail pairs on a given queue (ring->execlist_queue) until the
  106. * hardware is available. The queue serves a double purpose: we also use
  107. * it to keep track of the up to 2 contexts currently in the hardware
  108. * (usually one in execution and the other queued up by the GPU): We
  109. * only remove elements from the head of the queue when the hardware
  110. * informs us that an element has been completed.
  111. *
  112. * All accesses to the queue are mediated by a spinlock
  113. * (ring->execlist_lock).
  114. */
  115. /** Execlist link in the submission queue.*/
  116. struct list_head execlist_link;
  117. /** Execlists no. of times this request has been sent to the ELSP */
  118. int elsp_submitted;
  119. /** Execlists context hardware id. */
  120. unsigned int ctx_hw_id;
  121. };
  122. struct drm_i915_gem_request * __must_check
  123. i915_gem_request_alloc(struct intel_engine_cs *engine,
  124. struct i915_gem_context *ctx);
  125. void i915_gem_request_free(struct kref *req_ref);
  126. int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
  127. struct drm_file *file);
  128. void i915_gem_request_retire_upto(struct drm_i915_gem_request *req);
  129. static inline u32
  130. i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
  131. {
  132. return req ? req->seqno : 0;
  133. }
  134. static inline struct intel_engine_cs *
  135. i915_gem_request_get_engine(struct drm_i915_gem_request *req)
  136. {
  137. return req ? req->engine : NULL;
  138. }
  139. static inline struct drm_i915_gem_request *
  140. i915_gem_request_reference(struct drm_i915_gem_request *req)
  141. {
  142. if (req)
  143. kref_get(&req->ref);
  144. return req;
  145. }
  146. static inline void
  147. i915_gem_request_unreference(struct drm_i915_gem_request *req)
  148. {
  149. kref_put(&req->ref, i915_gem_request_free);
  150. }
  151. static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
  152. struct drm_i915_gem_request *src)
  153. {
  154. if (src)
  155. i915_gem_request_reference(src);
  156. if (*pdst)
  157. i915_gem_request_unreference(*pdst);
  158. *pdst = src;
  159. }
  160. void __i915_add_request(struct drm_i915_gem_request *req,
  161. struct drm_i915_gem_object *batch_obj,
  162. bool flush_caches);
  163. #define i915_add_request(req) \
  164. __i915_add_request(req, NULL, true)
  165. #define i915_add_request_no_flush(req) \
  166. __i915_add_request(req, NULL, false)
  167. struct intel_rps_client;
  168. int __i915_wait_request(struct drm_i915_gem_request *req,
  169. bool interruptible,
  170. s64 *timeout,
  171. struct intel_rps_client *rps);
  172. int __must_check i915_wait_request(struct drm_i915_gem_request *req);
  173. static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine);
  174. /**
  175. * Returns true if seq1 is later than seq2.
  176. */
  177. static inline bool i915_seqno_passed(u32 seq1, u32 seq2)
  178. {
  179. return (s32)(seq1 - seq2) >= 0;
  180. }
  181. static inline bool
  182. i915_gem_request_started(const struct drm_i915_gem_request *req)
  183. {
  184. return i915_seqno_passed(intel_engine_get_seqno(req->engine),
  185. req->previous_seqno);
  186. }
  187. static inline bool
  188. i915_gem_request_completed(const struct drm_i915_gem_request *req)
  189. {
  190. return i915_seqno_passed(intel_engine_get_seqno(req->engine),
  191. req->seqno);
  192. }
  193. bool __i915_spin_request(const struct drm_i915_gem_request *request,
  194. int state, unsigned long timeout_us);
  195. static inline bool i915_spin_request(const struct drm_i915_gem_request *request,
  196. int state, unsigned long timeout_us)
  197. {
  198. return (i915_gem_request_started(request) &&
  199. __i915_spin_request(request, state, timeout_us));
  200. }
  201. #endif /* I915_GEM_REQUEST_H */