summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c')
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 4eb00a0cb650..1ac916b24891 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -179,24 +179,18 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit)
struct etnaviv_gem_submit_bo *bo = &submit->bos[i];
struct dma_resv *robj = bo->obj->base.resv;
- if (!(bo->flags & ETNA_SUBMIT_BO_WRITE)) {
- ret = dma_resv_reserve_shared(robj, 1);
- if (ret)
- return ret;
- }
+ ret = dma_resv_reserve_fences(robj, 1);
+ if (ret)
+ return ret;
if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT)
continue;
- if (bo->flags & ETNA_SUBMIT_BO_WRITE) {
- ret = dma_resv_get_fences(robj, true, &bo->nr_shared,
- &bo->shared);
- if (ret)
- return ret;
- } else {
- bo->excl = dma_fence_get(dma_resv_excl_fence(robj));
- }
-
+ ret = drm_sched_job_add_implicit_dependencies(&submit->sched_job,
+ &bo->obj->base,
+ bo->flags & ETNA_SUBMIT_BO_WRITE);
+ if (ret)
+ return ret;
}
return ret;
@@ -208,14 +202,10 @@ static void submit_attach_object_fences(struct etnaviv_gem_submit *submit)
for (i = 0; i < submit->nr_bos; i++) {
struct drm_gem_object *obj = &submit->bos[i].obj->base;
+ bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE;
- if (submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE)
- dma_resv_add_excl_fence(obj->resv,
- submit->out_fence);
- else
- dma_resv_add_shared_fence(obj->resv,
- submit->out_fence);
-
+ dma_resv_add_fence(obj->resv, submit->out_fence, write ?
+ DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ);
submit_unlock_object(submit, i);
}
}
@@ -402,8 +392,6 @@ static void submit_cleanup(struct kref *kref)
wake_up_all(&submit->gpu->fence_event);
- if (submit->in_fence)
- dma_fence_put(submit->in_fence);
if (submit->out_fence) {
/* first remove from IDR, so fence can not be found anymore */
mutex_lock(&submit->gpu->fence_lock);
@@ -534,58 +522,69 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf,
ALIGN(args->stream_size, 8) + 8);
if (ret)
- goto err_submit_objects;
+ goto err_submit_put;
submit->ctx = file->driver_priv;
submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu);
submit->exec_state = args->exec_state;
submit->flags = args->flags;
+ ret = drm_sched_job_init(&submit->sched_job,
+ &ctx->sched_entity[args->pipe],
+ submit->ctx);
+ if (ret)
+ goto err_submit_put;
+
ret = submit_lookup_objects(submit, file, bos, args->nr_bos);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
if ((priv->mmu_global->version != ETNAVIV_IOMMU_V2) &&
!etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4,
relocs, args->nr_relocs)) {
ret = -EINVAL;
- goto err_submit_objects;
+ goto err_submit_job;
}
if (args->flags & ETNA_SUBMIT_FENCE_FD_IN) {
- submit->in_fence = sync_file_get_fence(args->fence_fd);
- if (!submit->in_fence) {
+ struct dma_fence *in_fence = sync_file_get_fence(args->fence_fd);
+ if (!in_fence) {
ret = -EINVAL;
- goto err_submit_objects;
+ goto err_submit_job;
}
+
+ ret = drm_sched_job_add_dependency(&submit->sched_job,
+ in_fence);
+ if (ret)
+ goto err_submit_job;
}
ret = submit_pin_objects(submit);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
ret = submit_reloc(submit, stream, args->stream_size / 4,
relocs, args->nr_relocs);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
ret = submit_perfmon_validate(submit, args->exec_state, pmrs);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
memcpy(submit->cmdbuf.vaddr, stream, args->stream_size);
ret = submit_lock_objects(submit, &ticket);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
ret = submit_fence_sync(submit);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
- ret = etnaviv_sched_push_job(&ctx->sched_entity[args->pipe], submit);
+ ret = etnaviv_sched_push_job(submit);
if (ret)
- goto err_submit_objects;
+ goto err_submit_job;
submit_attach_object_fences(submit);
@@ -599,7 +598,12 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
sync_file = sync_file_create(submit->out_fence);
if (!sync_file) {
ret = -ENOMEM;
- goto err_submit_objects;
+ /*
+ * When this late error is hit, the submit has already
+ * been handed over to the scheduler. At this point
+ * the sched_job must not be cleaned up.
+ */
+ goto err_submit_put;
}
fd_install(out_fence_fd, sync_file->file);
}
@@ -607,7 +611,10 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
args->fence_fd = out_fence_fd;
args->fence = submit->out_fence_id;
-err_submit_objects:
+err_submit_job:
+ if (ret)
+ drm_sched_job_cleanup(&submit->sched_job);
+err_submit_put:
etnaviv_submit_put(submit);
err_submit_ww_acquire: