* to v3d, so we don't attach dma-buf fences to them.
*/
static int
-v3d_lock_bo_reservations(struct drm_gem_object **bos,
- int bo_count,
+v3d_lock_bo_reservations(struct v3d_job *job,
struct ww_acquire_ctx *acquire_ctx)
{
int i, ret;
- ret = drm_gem_lock_reservations(bos, bo_count, acquire_ctx);
+ ret = drm_gem_lock_reservations(job->bo, job->bo_count, acquire_ctx);
if (ret)
return ret;
+ for (i = 0; i < job->bo_count; i++) {
+ ret = drm_gem_fence_array_add_implicit(&job->deps,
+ job->bo[i], true);
+ if (ret) {
+ drm_gem_unlock_reservations(job->bo, job->bo_count,
+ acquire_ctx);
+ return ret;
+ }
+ }
+
return 0;
}
v3d_job_free(struct kref *ref)
{
struct v3d_job *job = container_of(ref, struct v3d_job, refcount);
+ unsigned long index;
+ struct dma_fence *fence;
int i;
for (i = 0; i < job->bo_count; i++) {
}
kvfree(job->bo);
- dma_fence_put(job->in_fence);
+ xa_for_each(&job->deps, index, fence) {
+ dma_fence_put(fence);
+ }
+ xa_destroy(&job->deps);
+
dma_fence_put(job->irq_fence);
dma_fence_put(job->done_fence);
struct v3d_job *job, void (*free)(struct kref *ref),
u32 in_sync)
{
+ struct dma_fence *in_fence = NULL;
int ret;
job->v3d = v3d;
if (ret < 0)
return ret;
- ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &job->in_fence);
- if (ret == -EINVAL) {
- pm_runtime_put_autosuspend(v3d->dev);
- return ret;
- }
+ xa_init_flags(&job->deps, XA_FLAGS_ALLOC);
+
+ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &in_fence);
+ if (ret == -EINVAL)
+ goto fail;
+
+ ret = drm_gem_fence_array_add(&job->deps, in_fence);
+ if (ret)
+ goto fail;
kref_init(&job->refcount);
return 0;
+fail:
+ xa_destroy(&job->deps);
+ pm_runtime_put_autosuspend(v3d->dev);
+ return ret;
}
static int
if (ret)
goto fail;
- ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count,
- &acquire_ctx);
+ ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx);
if (ret)
goto fail;
if (ret)
goto fail_unreserve;
- render->bin_done_fence = dma_fence_get(bin->base.done_fence);
+ ret = drm_gem_fence_array_add(&render->base.deps,
+ dma_fence_get(bin->base.done_fence));
+ if (ret)
+ goto fail_unreserve;
}
ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER);
}
spin_unlock(&file_priv->table_lock);
- ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count,
- &acquire_ctx);
+ ret = v3d_lock_bo_reservations(&job->base, &acquire_ctx);
if (ret)
goto fail;
if (ret)
goto fail;
- ret = v3d_lock_bo_reservations(clean_job->base.bo,
- clean_job->base.bo_count,
- &acquire_ctx);
+ ret = v3d_lock_bo_reservations(clean_job, &acquire_ctx);
if (ret)
goto fail;
if (ret)
goto fail_unreserve;
- clean_job->in_fence = dma_fence_get(job->base.done_fence);
+ ret = drm_gem_fence_array_add(&clean_job->deps,
+ dma_fence_get(job->base.done_fence));
+ if (ret)
+ goto fail_unreserve;
+
ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN);
if (ret)
goto fail_unreserve;
struct drm_sched_entity *s_entity)
{
struct v3d_job *job = to_v3d_job(sched_job);
- struct dma_fence *fence;
-
- fence = job->in_fence;
- if (fence) {
- job->in_fence = NULL;
- return fence;
- }
/* XXX: Wait on a fence for switching the GMP if necessary,
* and then do so.
*/
- return NULL;
-}
+ if (!xa_empty(&job->deps))
+ return xa_erase(&job->deps, job->last_dep++);
-/**
- * Returns the fences that the render job depends on, one by one.
- * v3d_job_run() won't be called until all of them have been signaled.
- */
-static struct dma_fence *
-v3d_render_job_dependency(struct drm_sched_job *sched_job,
- struct drm_sched_entity *s_entity)
-{
- struct v3d_render_job *job = to_render_job(sched_job);
- struct dma_fence *fence;
-
- fence = v3d_job_dependency(sched_job, s_entity);
- if (fence)
- return fence;
-
- /* If we had a bin job, the render job definitely depends on
- * it. We first have to wait for bin to be scheduled, so that
- * its done_fence is created.
- */
- fence = job->bin_done_fence;
- if (fence) {
- job->bin_done_fence = NULL;
- return fence;
- }
-
- return fence;
+ return NULL;
}
static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)
};
static const struct drm_sched_backend_ops v3d_render_sched_ops = {
- .dependency = v3d_render_job_dependency,
+ .dependency = v3d_job_dependency,
.run_job = v3d_render_job_run,
.timedout_job = v3d_render_job_timedout,
.free_job = v3d_job_free,