Merge drm/drm-next into drm-misc-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / scheduler / sched_main.c
index fcd5bd7e5e8e969fbdbdc7c9b93d1fa5b0f8cdd9..172e63c87bfcf38bae7730211a666e9588bff5e8 100644 (file)
  *    the hardware.
  *
  * The jobs in a entity are always scheduled in the order that they were pushed.
+ *
+ * Note that once a job was taken from the entities queue and pushed to the
+ * hardware, i.e. the pending queue, the entity must not be referenced anymore
+ * through the jobs entity pointer.
  */
 
 #include <linux/kthread.h>
@@ -258,7 +262,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
  *
  * Finish the job's fence and wake up the worker thread.
  */
-static void drm_sched_job_done(struct drm_sched_job *s_job)
+static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
 {
        struct drm_sched_fence *s_fence = s_job->s_fence;
        struct drm_gpu_scheduler *sched = s_fence->sched;
@@ -269,7 +273,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
        trace_drm_sched_process_job(s_fence);
 
        dma_fence_get(&s_fence->finished);
-       drm_sched_fence_finished(s_fence);
+       drm_sched_fence_finished(s_fence, result);
        dma_fence_put(&s_fence->finished);
        wake_up_interruptible(&sched->wake_up_worker);
 }
@@ -283,7 +287,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb)
 {
        struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
 
-       drm_sched_job_done(s_job);
+       drm_sched_job_done(s_job, f->error);
 }
 
 /**
@@ -534,12 +538,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
                        r = dma_fence_add_callback(fence, &s_job->cb,
                                                   drm_sched_job_done_cb);
                        if (r == -ENOENT)
-                               drm_sched_job_done(s_job);
+                               drm_sched_job_done(s_job, fence->error);
                        else if (r)
                                DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
                                          r);
                } else
-                       drm_sched_job_done(s_job);
+                       drm_sched_job_done(s_job, -ECANCELED);
        }
 
        if (full_recovery) {
@@ -1050,15 +1054,13 @@ static int drm_sched_main(void *param)
                        r = dma_fence_add_callback(fence, &sched_job->cb,
                                                   drm_sched_job_done_cb);
                        if (r == -ENOENT)
-                               drm_sched_job_done(sched_job);
+                               drm_sched_job_done(sched_job, fence->error);
                        else if (r)
                                DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
                                          r);
                } else {
-                       if (IS_ERR(fence))
-                               dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
-
-                       drm_sched_job_done(sched_job);
+                       drm_sched_job_done(sched_job, IS_ERR(fence) ?
+                                          PTR_ERR(fence) : 0);
                }
 
                wake_up(&sched->job_scheduled);