aboutsummaryrefslogtreecommitdiffstats
path: root/include/drm/gpu_scheduler.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm/gpu_scheduler.h')
-rw-r--r--include/drm/gpu_scheduler.h174
1 files changed, 134 insertions, 40 deletions
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index dec655894d08..21c648b0b2a1 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -27,6 +27,8 @@
27#include <drm/spsc_queue.h> 27#include <drm/spsc_queue.h>
28#include <linux/dma-fence.h> 28#include <linux/dma-fence.h>
29 29
30#define MAX_WAIT_SCHED_ENTITY_Q_EMPTY msecs_to_jiffies(1000)
31
30struct drm_gpu_scheduler; 32struct drm_gpu_scheduler;
31struct drm_sched_rq; 33struct drm_sched_rq;
32 34
@@ -43,18 +45,37 @@ enum drm_sched_priority {
43}; 45};
44 46
45/** 47/**
46 * drm_sched_entity - A wrapper around a job queue (typically attached 48 * struct drm_sched_entity - A wrapper around a job queue (typically
47 * to the DRM file_priv). 49 * attached to the DRM file_priv).
50 *
51 * @list: used to append this struct to the list of entities in the
52 * runqueue.
53 * @rq: runqueue to which this entity belongs.
54 * @rq_lock: lock to modify the runqueue to which this entity belongs.
55 * @job_queue: the list of jobs of this entity.
56 * @fence_seq: a linearly increasing seqno incremented with each
57 * new &drm_sched_fence which is part of the entity.
58 * @fence_context: a unique context for all the fences which belong
59 * to this entity.
60 * The &drm_sched_fence.scheduled uses the
61 * fence_context but &drm_sched_fence.finished uses
62 * fence_context + 1.
63 * @dependency: the dependency fence of the job which is on the top
64 * of the job queue.
65 * @cb: callback for the dependency fence above.
66 * @guilty: points to ctx's guilty.
67 * @fini_status: contains the exit status in case the process was signalled.
68 * @last_scheduled: points to the finished fence of the last scheduled job.
69 * @last_user: last group leader pushing a job into the entity.
48 * 70 *
49 * Entities will emit jobs in order to their corresponding hardware 71 * Entities will emit jobs in order to their corresponding hardware
50 * ring, and the scheduler will alternate between entities based on 72 * ring, and the scheduler will alternate between entities based on
51 * scheduling policy. 73 * scheduling policy.
52*/ 74 */
53struct drm_sched_entity { 75struct drm_sched_entity {
54 struct list_head list; 76 struct list_head list;
55 struct drm_sched_rq *rq; 77 struct drm_sched_rq *rq;
56 spinlock_t rq_lock; 78 spinlock_t rq_lock;
57 struct drm_gpu_scheduler *sched;
58 79
59 struct spsc_queue job_queue; 80 struct spsc_queue job_queue;
60 81
@@ -63,47 +84,98 @@ struct drm_sched_entity {
63 84
64 struct dma_fence *dependency; 85 struct dma_fence *dependency;
65 struct dma_fence_cb cb; 86 struct dma_fence_cb cb;
66 atomic_t *guilty; /* points to ctx's guilty */ 87 atomic_t *guilty;
67 int fini_status; 88 struct dma_fence *last_scheduled;
68 struct dma_fence *last_scheduled; 89 struct task_struct *last_user;
69}; 90};
70 91
71/** 92/**
93 * struct drm_sched_rq - queue of entities to be scheduled.
94 *
95 * @lock: to modify the entities list.
96 * @sched: the scheduler to which this rq belongs to.
97 * @entities: list of the entities to be scheduled.
98 * @current_entity: the entity which is to be scheduled.
99 *
72 * Run queue is a set of entities scheduling command submissions for 100 * Run queue is a set of entities scheduling command submissions for
73 * one specific ring. It implements the scheduling policy that selects 101 * one specific ring. It implements the scheduling policy that selects
74 * the next entity to emit commands from. 102 * the next entity to emit commands from.
75*/ 103 */
76struct drm_sched_rq { 104struct drm_sched_rq {
77 spinlock_t lock; 105 spinlock_t lock;
106 struct drm_gpu_scheduler *sched;
78 struct list_head entities; 107 struct list_head entities;
79 struct drm_sched_entity *current_entity; 108 struct drm_sched_entity *current_entity;
80}; 109};
81 110
111/**
112 * struct drm_sched_fence - fences corresponding to the scheduling of a job.
113 */
82struct drm_sched_fence { 114struct drm_sched_fence {
115 /**
116 * @scheduled: this fence is what will be signaled by the scheduler
117 * when the job is scheduled.
118 */
83 struct dma_fence scheduled; 119 struct dma_fence scheduled;
84 120
85 /* This fence is what will be signaled by the scheduler when 121 /**
86 * the job is completed. 122 * @finished: this fence is what will be signaled by the scheduler
87 * 123 * when the job is completed.
88 * When setting up an out fence for the job, you should use 124 *
89 * this, since it's available immediately upon 125 * When setting up an out fence for the job, you should use
90 * drm_sched_job_init(), and the fence returned by the driver 126 * this, since it's available immediately upon
91 * from run_job() won't be created until the dependencies have 127 * drm_sched_job_init(), and the fence returned by the driver
92 * resolved. 128 * from run_job() won't be created until the dependencies have
93 */ 129 * resolved.
130 */
94 struct dma_fence finished; 131 struct dma_fence finished;
95 132
133 /**
134 * @cb: the callback for the parent fence below.
135 */
96 struct dma_fence_cb cb; 136 struct dma_fence_cb cb;
137 /**
138 * @parent: the fence returned by &drm_sched_backend_ops.run_job
139 * when scheduling the job on hardware. We signal the
140 * &drm_sched_fence.finished fence once parent is signalled.
141 */
97 struct dma_fence *parent; 142 struct dma_fence *parent;
143 /**
144 * @sched: the scheduler instance to which the job having this struct
145 * belongs to.
146 */
98 struct drm_gpu_scheduler *sched; 147 struct drm_gpu_scheduler *sched;
148 /**
149 * @lock: the lock used by the scheduled and the finished fences.
150 */
99 spinlock_t lock; 151 spinlock_t lock;
152 /**
153 * @owner: job owner for debugging
154 */
100 void *owner; 155 void *owner;
101}; 156};
102 157
103struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); 158struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);
104 159
105/** 160/**
106 * drm_sched_job - A job to be run by an entity. 161 * struct drm_sched_job - A job to be run by an entity.
162 *
163 * @queue_node: used to append this struct to the queue of jobs in an entity.
164 * @sched: the scheduler instance on which this job is scheduled.
165 * @s_fence: contains the fences for the scheduling of job.
166 * @finish_cb: the callback for the finished fence.
167 * @finish_work: schedules the function @drm_sched_job_finish once the job has
168 * finished to remove the job from the
169 * @drm_gpu_scheduler.ring_mirror_list.
170 * @node: used to append this struct to the @drm_gpu_scheduler.ring_mirror_list.
171 * @work_tdr: schedules a delayed call to @drm_sched_job_timedout after the timeout
172 * interval is over.
173 * @id: a unique id assigned to each job scheduled on the scheduler.
174 * @karma: increment on every hang caused by this job. If this exceeds the hang
175 * limit of the scheduler then the job is marked guilty and will not
176 * be scheduled further.
177 * @s_priority: the priority of the job.
178 * @entity: the entity to which this job belongs.
107 * 179 *
108 * A job is created by the driver using drm_sched_job_init(), and 180 * A job is created by the driver using drm_sched_job_init(), and
109 * should call drm_sched_entity_push_job() once it wants the scheduler 181 * should call drm_sched_entity_push_job() once it wants the scheduler
@@ -130,38 +202,64 @@ static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job,
130} 202}
131 203
132/** 204/**
205 * struct drm_sched_backend_ops
206 *
133 * Define the backend operations called by the scheduler, 207 * Define the backend operations called by the scheduler,
134 * these functions should be implemented in driver side 208 * these functions should be implemented in driver side.
135*/ 209 */
136struct drm_sched_backend_ops { 210struct drm_sched_backend_ops {
137 /* Called when the scheduler is considering scheduling this 211 /**
138 * job next, to get another struct dma_fence for this job to 212 * @dependency: Called when the scheduler is considering scheduling
213 * this job next, to get another struct dma_fence for this job to
139 * block on. Once it returns NULL, run_job() may be called. 214 * block on. Once it returns NULL, run_job() may be called.
140 */ 215 */
141 struct dma_fence *(*dependency)(struct drm_sched_job *sched_job, 216 struct dma_fence *(*dependency)(struct drm_sched_job *sched_job,
142 struct drm_sched_entity *s_entity); 217 struct drm_sched_entity *s_entity);
143 218
144 /* Called to execute the job once all of the dependencies have 219 /**
145 * been resolved. This may be called multiple times, if 220 * @run_job: Called to execute the job once all of the dependencies
221 * have been resolved. This may be called multiple times, if
146 * timedout_job() has happened and drm_sched_job_recovery() 222 * timedout_job() has happened and drm_sched_job_recovery()
147 * decides to try it again. 223 * decides to try it again.
148 */ 224 */
149 struct dma_fence *(*run_job)(struct drm_sched_job *sched_job); 225 struct dma_fence *(*run_job)(struct drm_sched_job *sched_job);
150 226
151 /* Called when a job has taken too long to execute, to trigger 227 /**
152 * GPU recovery. 228 * @timedout_job: Called when a job has taken too long to execute,
229 * to trigger GPU recovery.
153 */ 230 */
154 void (*timedout_job)(struct drm_sched_job *sched_job); 231 void (*timedout_job)(struct drm_sched_job *sched_job);
155 232
156 /* Called once the job's finished fence has been signaled and 233 /**
157 * it's time to clean it up. 234 * @free_job: Called once the job's finished fence has been signaled
235 * and it's time to clean it up.
158 */ 236 */
159 void (*free_job)(struct drm_sched_job *sched_job); 237 void (*free_job)(struct drm_sched_job *sched_job);
160}; 238};
161 239
162/** 240/**
163 * One scheduler is implemented for each hardware ring 241 * struct drm_gpu_scheduler
164*/ 242 *
243 * @ops: backend operations provided by the driver.
244 * @hw_submission_limit: the max size of the hardware queue.
245 * @timeout: the time after which a job is removed from the scheduler.
246 * @name: name of the ring for which this scheduler is being used.
247 * @sched_rq: priority wise array of run queues.
248 * @wake_up_worker: the wait queue on which the scheduler sleeps until a job
249 * is ready to be scheduled.
250 * @job_scheduled: once @drm_sched_entity_do_release is called the scheduler
251 * waits on this wait queue until all the scheduled jobs are
252 * finished.
253 * @hw_rq_count: the number of jobs currently in the hardware queue.
254 * @job_id_count: used to assign unique id to the each job.
255 * @thread: the kthread on which the scheduler which run.
256 * @ring_mirror_list: the list of jobs which are currently in the job queue.
257 * @job_list_lock: lock to protect the ring_mirror_list.
258 * @hang_limit: once the hangs by a job crosses this limit then it is marked
259 * guilty and it will be considered for scheduling further.
260 *
261 * One scheduler is implemented for each hardware ring.
262 */
165struct drm_gpu_scheduler { 263struct drm_gpu_scheduler {
166 const struct drm_sched_backend_ops *ops; 264 const struct drm_sched_backend_ops *ops;
167 uint32_t hw_submission_limit; 265 uint32_t hw_submission_limit;
@@ -184,16 +282,13 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
184 const char *name); 282 const char *name);
185void drm_sched_fini(struct drm_gpu_scheduler *sched); 283void drm_sched_fini(struct drm_gpu_scheduler *sched);
186 284
187int drm_sched_entity_init(struct drm_gpu_scheduler *sched, 285int drm_sched_entity_init(struct drm_sched_entity *entity,
188 struct drm_sched_entity *entity, 286 struct drm_sched_rq **rq_list,
189 struct drm_sched_rq *rq, 287 unsigned int num_rq_list,
190 atomic_t *guilty); 288 atomic_t *guilty);
191void drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, 289long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
192 struct drm_sched_entity *entity); 290void drm_sched_entity_fini(struct drm_sched_entity *entity);
193void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, 291void drm_sched_entity_destroy(struct drm_sched_entity *entity);
194 struct drm_sched_entity *entity);
195void drm_sched_entity_fini(struct drm_gpu_scheduler *sched,
196 struct drm_sched_entity *entity);
197void drm_sched_entity_push_job(struct drm_sched_job *sched_job, 292void drm_sched_entity_push_job(struct drm_sched_job *sched_job,
198 struct drm_sched_entity *entity); 293 struct drm_sched_entity *entity);
199void drm_sched_entity_set_rq(struct drm_sched_entity *entity, 294void drm_sched_entity_set_rq(struct drm_sched_entity *entity,
@@ -204,7 +299,6 @@ struct drm_sched_fence *drm_sched_fence_create(
204void drm_sched_fence_scheduled(struct drm_sched_fence *fence); 299void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
205void drm_sched_fence_finished(struct drm_sched_fence *fence); 300void drm_sched_fence_finished(struct drm_sched_fence *fence);
206int drm_sched_job_init(struct drm_sched_job *job, 301int drm_sched_job_init(struct drm_sched_job *job,
207 struct drm_gpu_scheduler *sched,
208 struct drm_sched_entity *entity, 302 struct drm_sched_entity *entity,
209 void *owner); 303 void *owner);
210void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched, 304void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched,