diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 7f9a71022e5e..53deae1a2eda 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -657,6 +657,9 @@ v3d_cpu_job_run(struct drm_sched_job *sched_job) struct v3d_cpu_job *job = to_cpu_job(sched_job); struct v3d_dev *v3d = job->base.v3d; + if (unlikely(job->base.base.s_fence->finished.error)) + return NULL; + if (job->job_type >= ARRAY_SIZE(cpu_job_function)) { drm_dbg(&v3d->drm, "Unknown CPU job: %d\n", job->job_type); return NULL; @@ -680,6 +683,9 @@ v3d_cache_clean_job_run(struct drm_sched_job *sched_job) struct v3d_job *job = to_v3d_job(sched_job); struct v3d_dev *v3d = job->v3d; + if (unlikely(job->base.s_fence->finished.error)) + return NULL; + v3d_job_start_stats(job); v3d_clean_caches(v3d); diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c index cee48acd25d9..ee2ac2540ed5 100644 --- a/drivers/gpu/drm/v3d/v3d_submit.c +++ b/drivers/gpu/drm/v3d/v3d_submit.c @@ -368,19 +368,6 @@ v3d_submit_process_post_deps(struct v3d_submit *submit, struct drm_syncobj *sync } } -static void -v3d_push_job(struct v3d_job *job) -{ - drm_sched_job_arm(&job->base); - - job->done_fence = dma_fence_get(&job->base.s_fence->finished); - - /* put by scheduler job completion */ - kref_get(&job->refcount); - - drm_sched_entity_push_job(&job->base); -} - static int v3d_submit_jobs(struct v3d_submit *submit, struct drm_syncobj *sync_out, struct v3d_submit_ext *se) @@ -393,16 +380,23 @@ v3d_submit_jobs(struct v3d_submit *submit, struct drm_syncobj *sync_out, for (int i = 0; i < submit->job_count; i++) { struct v3d_job *job = submit->jobs[i]; - v3d_push_job(job); + drm_sched_job_arm(&job->base); + job->done_fence = dma_fence_get(&job->base.s_fence->finished); - if (i + 1 < submit->job_count) { - ret = drm_sched_job_add_dependency(&submit->jobs[i + 1]->base, - dma_fence_get(job->done_fence)); - if (ret) - goto err; - } + /* put by scheduler job completion */ + kref_get(&job->refcount); } + for (int i = 1; i < submit->job_count; i++) { + ret = drm_sched_job_add_dependency(&submit->jobs[i]->base, + dma_fence_get(submit->jobs[i - 1]->done_fence)); + if (ret) + goto err; + } + + for (int i = 0; i < submit->job_count; i++) + drm_sched_entity_push_job(&submit->jobs[i]->base); + mutex_unlock(&v3d->sched_lock); v3d_submit_attach_object_fences(submit); @@ -414,7 +408,18 @@ v3d_submit_jobs(struct v3d_submit *submit, struct drm_syncobj *sync_out, return 0; err: + /* Mark every armed job as failed so run_job() skips execution */ + for (int i = 0; i < submit->job_count; i++) + dma_fence_set_error(&submit->jobs[i]->base.s_fence->finished, ret); + + for (int i = 0; i < submit->job_count; i++) + drm_sched_entity_push_job(&submit->jobs[i]->base); + mutex_unlock(&v3d->sched_lock); + + v3d_submit_unlock_reservations(submit); + v3d_submit_put_jobs(submit); + return ret; } @@ -1102,14 +1107,13 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, ret = v3d_submit_jobs(&submit, sync_out, &se); if (ret) - goto fail_unreserve; + goto fail_submit; return 0; -fail_unreserve: - v3d_submit_unlock_reservations(&submit); fail: v3d_submit_cleanup_jobs(&submit); +fail_submit: v3d_submit_put_post_deps(sync_out, &se); return ret; @@ -1200,14 +1204,13 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, ret = v3d_submit_jobs(&submit, sync_out, &se); if (ret) - goto fail_unreserve; + goto fail_submit; return 0; -fail_unreserve: - v3d_submit_unlock_reservations(&submit); fail: v3d_submit_cleanup_jobs(&submit); +fail_submit: v3d_submit_put_post_deps(sync_out, &se); return ret; @@ -1276,14 +1279,13 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data, ret = v3d_submit_jobs(&submit, sync_out, &se); if (ret) - goto fail_unreserve; + goto fail_submit; return 0; -fail_unreserve: - v3d_submit_unlock_reservations(&submit); fail: v3d_submit_cleanup_jobs(&submit); +fail_submit: v3d_submit_put_post_deps(sync_out, &se); return ret; @@ -1384,14 +1386,13 @@ v3d_submit_cpu_ioctl(struct drm_device *dev, void *data, ret = v3d_submit_jobs(&submit, NULL, &se); if (ret) - goto fail_unreserve; + goto fail_submit; return 0; -fail_unreserve: - v3d_submit_unlock_reservations(&submit); fail: v3d_submit_cleanup_jobs(&submit); +fail_submit: v3d_submit_put_post_deps(NULL, &se); return ret;