aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/scheduler/sched_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/scheduler/sched_main.c')
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 4e8505d51795..44fe587aaef9 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -182,6 +182,20 @@ bool drm_sched_dependency_optimized(struct dma_fence* fence,
182} 182}
183EXPORT_SYMBOL(drm_sched_dependency_optimized); 183EXPORT_SYMBOL(drm_sched_dependency_optimized);
184 184
185/**
186 * drm_sched_start_timeout - start timeout for reset worker
187 *
188 * @sched: scheduler instance to start the worker for
189 *
190 * Start the timeout for the given scheduler.
191 */
192static void drm_sched_start_timeout(struct drm_gpu_scheduler *sched)
193{
194 if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
195 !list_empty(&sched->ring_mirror_list))
196 schedule_delayed_work(&sched->work_tdr, sched->timeout);
197}
198
185/* job_finish is called after hw fence signaled 199/* job_finish is called after hw fence signaled
186 */ 200 */
187static void drm_sched_job_finish(struct work_struct *work) 201static void drm_sched_job_finish(struct work_struct *work)
@@ -203,9 +217,7 @@ static void drm_sched_job_finish(struct work_struct *work)
203 /* remove job from ring_mirror_list */ 217 /* remove job from ring_mirror_list */
204 list_del(&s_job->node); 218 list_del(&s_job->node);
205 /* queue TDR for next job */ 219 /* queue TDR for next job */
206 if (sched->timeout != MAX_SCHEDULE_TIMEOUT && 220 drm_sched_start_timeout(sched);
207 !list_empty(&sched->ring_mirror_list))
208 schedule_delayed_work(&sched->work_tdr, sched->timeout);
209 spin_unlock(&sched->job_list_lock); 221 spin_unlock(&sched->job_list_lock);
210 222
211 dma_fence_put(&s_job->s_fence->finished); 223 dma_fence_put(&s_job->s_fence->finished);
@@ -229,10 +241,7 @@ static void drm_sched_job_begin(struct drm_sched_job *s_job)
229 241
230 spin_lock(&sched->job_list_lock); 242 spin_lock(&sched->job_list_lock);
231 list_add_tail(&s_job->node, &sched->ring_mirror_list); 243 list_add_tail(&s_job->node, &sched->ring_mirror_list);
232 if (sched->timeout != MAX_SCHEDULE_TIMEOUT && 244 drm_sched_start_timeout(sched);
233 list_first_entry_or_null(&sched->ring_mirror_list,
234 struct drm_sched_job, node) == s_job)
235 schedule_delayed_work(&sched->work_tdr, sched->timeout);
236 spin_unlock(&sched->job_list_lock); 245 spin_unlock(&sched->job_list_lock);
237} 246}
238 247
@@ -240,13 +249,41 @@ static void drm_sched_job_timedout(struct work_struct *work)
240{ 249{
241 struct drm_gpu_scheduler *sched; 250 struct drm_gpu_scheduler *sched;
242 struct drm_sched_job *job; 251 struct drm_sched_job *job;
252 int r;
243 253
244 sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work); 254 sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
255
256 spin_lock(&sched->job_list_lock);
257 list_for_each_entry_reverse(job, &sched->ring_mirror_list, node) {
258 struct drm_sched_fence *fence = job->s_fence;
259
260 if (!dma_fence_remove_callback(fence->parent, &fence->cb))
261 goto already_signaled;
262 }
263
245 job = list_first_entry_or_null(&sched->ring_mirror_list, 264 job = list_first_entry_or_null(&sched->ring_mirror_list,
246 struct drm_sched_job, node); 265 struct drm_sched_job, node);
266 spin_unlock(&sched->job_list_lock);
247 267
248 if (job) 268 if (job)
249 job->sched->ops->timedout_job(job); 269 sched->ops->timedout_job(job);
270
271 spin_lock(&sched->job_list_lock);
272 list_for_each_entry(job, &sched->ring_mirror_list, node) {
273 struct drm_sched_fence *fence = job->s_fence;
274
275 if (!fence->parent || !list_empty(&fence->cb.node))
276 continue;
277
278 r = dma_fence_add_callback(fence->parent, &fence->cb,
279 drm_sched_process_job);
280 if (r)
281 drm_sched_process_job(fence->parent, &fence->cb);
282
283already_signaled:
284 ;
285 }
286 spin_unlock(&sched->job_list_lock);
250} 287}
251 288
252/** 289/**
@@ -313,11 +350,6 @@ void drm_sched_job_recovery(struct drm_gpu_scheduler *sched)
313 int r; 350 int r;
314 351
315 spin_lock(&sched->job_list_lock); 352 spin_lock(&sched->job_list_lock);
316 s_job = list_first_entry_or_null(&sched->ring_mirror_list,
317 struct drm_sched_job, node);
318 if (s_job && sched->timeout != MAX_SCHEDULE_TIMEOUT)
319 schedule_delayed_work(&sched->work_tdr, sched->timeout);
320
321 list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { 353 list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
322 struct drm_sched_fence *s_fence = s_job->s_fence; 354 struct drm_sched_fence *s_fence = s_job->s_fence;
323 struct dma_fence *fence; 355 struct dma_fence *fence;
@@ -350,6 +382,7 @@ void drm_sched_job_recovery(struct drm_gpu_scheduler *sched)
350 } 382 }
351 spin_lock(&sched->job_list_lock); 383 spin_lock(&sched->job_list_lock);
352 } 384 }
385 drm_sched_start_timeout(sched);
353 spin_unlock(&sched->job_list_lock); 386 spin_unlock(&sched->job_list_lock);
354} 387}
355EXPORT_SYMBOL(drm_sched_job_recovery); 388EXPORT_SYMBOL(drm_sched_job_recovery);