gpu_scheduler.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright 2015 Advanced Micro Devices, Inc.
  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 shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. */
  23. #ifndef _GPU_SCHEDULER_H_
  24. #define _GPU_SCHEDULER_H_
  25. #include <linux/kfifo.h>
  26. #include <linux/dma-fence.h>
  27. #include "spsc_queue.h"
  28. struct amd_gpu_scheduler;
  29. struct amd_sched_rq;
  30. enum amd_sched_priority {
  31. AMD_SCHED_PRIORITY_MIN,
  32. AMD_SCHED_PRIORITY_LOW = AMD_SCHED_PRIORITY_MIN,
  33. AMD_SCHED_PRIORITY_NORMAL,
  34. AMD_SCHED_PRIORITY_HIGH_SW,
  35. AMD_SCHED_PRIORITY_HIGH_HW,
  36. AMD_SCHED_PRIORITY_KERNEL,
  37. AMD_SCHED_PRIORITY_MAX,
  38. AMD_SCHED_PRIORITY_INVALID = -1,
  39. AMD_SCHED_PRIORITY_UNSET = -2
  40. };
  41. /**
  42. * A scheduler entity is a wrapper around a job queue or a group
  43. * of other entities. Entities take turns emitting jobs from their
  44. * job queues to corresponding hardware ring based on scheduling
  45. * policy.
  46. */
  47. struct amd_sched_entity {
  48. struct list_head list;
  49. struct amd_sched_rq *rq;
  50. spinlock_t rq_lock;
  51. struct amd_gpu_scheduler *sched;
  52. spinlock_t queue_lock;
  53. struct spsc_queue job_queue;
  54. atomic_t fence_seq;
  55. uint64_t fence_context;
  56. struct dma_fence *dependency;
  57. struct dma_fence_cb cb;
  58. atomic_t *guilty; /* points to ctx's guilty */
  59. };
  60. /**
  61. * Run queue is a set of entities scheduling command submissions for
  62. * one specific ring. It implements the scheduling policy that selects
  63. * the next entity to emit commands from.
  64. */
  65. struct amd_sched_rq {
  66. spinlock_t lock;
  67. struct list_head entities;
  68. struct amd_sched_entity *current_entity;
  69. };
  70. struct amd_sched_fence {
  71. struct dma_fence scheduled;
  72. struct dma_fence finished;
  73. struct dma_fence_cb cb;
  74. struct dma_fence *parent;
  75. struct amd_gpu_scheduler *sched;
  76. spinlock_t lock;
  77. void *owner;
  78. };
  79. struct amd_sched_job {
  80. struct spsc_node queue_node;
  81. struct amd_gpu_scheduler *sched;
  82. struct amd_sched_fence *s_fence;
  83. struct dma_fence_cb finish_cb;
  84. struct work_struct finish_work;
  85. struct list_head node;
  86. struct delayed_work work_tdr;
  87. uint64_t id;
  88. atomic_t karma;
  89. enum amd_sched_priority s_priority;
  90. };
  91. extern const struct dma_fence_ops amd_sched_fence_ops_scheduled;
  92. extern const struct dma_fence_ops amd_sched_fence_ops_finished;
  93. static inline struct amd_sched_fence *to_amd_sched_fence(struct dma_fence *f)
  94. {
  95. if (f->ops == &amd_sched_fence_ops_scheduled)
  96. return container_of(f, struct amd_sched_fence, scheduled);
  97. if (f->ops == &amd_sched_fence_ops_finished)
  98. return container_of(f, struct amd_sched_fence, finished);
  99. return NULL;
  100. }
  101. static inline bool amd_sched_invalidate_job(struct amd_sched_job *s_job, int threshold)
  102. {
  103. return (s_job && atomic_inc_return(&s_job->karma) > threshold);
  104. }
  105. /**
  106. * Define the backend operations called by the scheduler,
  107. * these functions should be implemented in driver side
  108. */
  109. struct amd_sched_backend_ops {
  110. struct dma_fence *(*dependency)(struct amd_sched_job *sched_job,
  111. struct amd_sched_entity *s_entity);
  112. struct dma_fence *(*run_job)(struct amd_sched_job *sched_job);
  113. void (*timedout_job)(struct amd_sched_job *sched_job);
  114. void (*free_job)(struct amd_sched_job *sched_job);
  115. };
  116. /**
  117. * One scheduler is implemented for each hardware ring
  118. */
  119. struct amd_gpu_scheduler {
  120. const struct amd_sched_backend_ops *ops;
  121. uint32_t hw_submission_limit;
  122. long timeout;
  123. const char *name;
  124. struct amd_sched_rq sched_rq[AMD_SCHED_PRIORITY_MAX];
  125. wait_queue_head_t wake_up_worker;
  126. wait_queue_head_t job_scheduled;
  127. atomic_t hw_rq_count;
  128. atomic64_t job_id_count;
  129. struct task_struct *thread;
  130. struct list_head ring_mirror_list;
  131. spinlock_t job_list_lock;
  132. int hang_limit;
  133. };
  134. int amd_sched_init(struct amd_gpu_scheduler *sched,
  135. const struct amd_sched_backend_ops *ops,
  136. uint32_t hw_submission, unsigned hang_limit, long timeout, const char *name);
  137. void amd_sched_fini(struct amd_gpu_scheduler *sched);
  138. int amd_sched_entity_init(struct amd_gpu_scheduler *sched,
  139. struct amd_sched_entity *entity,
  140. struct amd_sched_rq *rq,
  141. uint32_t jobs, atomic_t* guilty);
  142. void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
  143. struct amd_sched_entity *entity);
  144. void amd_sched_entity_push_job(struct amd_sched_job *sched_job,
  145. struct amd_sched_entity *entity);
  146. void amd_sched_entity_set_rq(struct amd_sched_entity *entity,
  147. struct amd_sched_rq *rq);
  148. int amd_sched_fence_slab_init(void);
  149. void amd_sched_fence_slab_fini(void);
  150. struct amd_sched_fence *amd_sched_fence_create(
  151. struct amd_sched_entity *s_entity, void *owner);
  152. void amd_sched_fence_scheduled(struct amd_sched_fence *fence);
  153. void amd_sched_fence_finished(struct amd_sched_fence *fence);
  154. int amd_sched_job_init(struct amd_sched_job *job,
  155. struct amd_gpu_scheduler *sched,
  156. struct amd_sched_entity *entity,
  157. void *owner);
  158. void amd_sched_hw_job_reset(struct amd_gpu_scheduler *sched, struct amd_sched_job *job);
  159. void amd_sched_job_recovery(struct amd_gpu_scheduler *sched);
  160. bool amd_sched_dependency_optimized(struct dma_fence* fence,
  161. struct amd_sched_entity *entity);
  162. void amd_sched_job_kickout(struct amd_sched_job *s_job);
  163. #endif