// SPDX-License-Identifier: GPL-2.0-only OR MIT
/* Copyright (c) 2023 Imagination Technologies Ltd. */

#include "pvr_context.h"
#include "pvr_device.h"
#include "pvr_drv.h"
#include "pvr_gem.h"
#include "pvr_hwrt.h"
#include "pvr_job.h"
#include "pvr_mmu.h"
#include "pvr_power.h"
#include "pvr_rogue_fwif.h"
#include "pvr_rogue_fwif_client.h"
#include "pvr_stream.h"
#include "pvr_stream_defs.h"
#include "pvr_sync.h"

#include <drm/drm_exec.h>
#include <drm/drm_gem.h>
#include <linux/types.h>
#include <uapi/drm/pvr_drm.h>

static void pvr_job_release(struct kref *kref)
{
	struct pvr_job *job = container_of(kref, struct pvr_job, ref_count);

	xa_erase(&job->pvr_dev->job_ids, job->id);

	pvr_hwrt_data_put(job->hwrt);
	pvr_context_put(job->ctx);

	WARN_ON(job->paired_job);

	pvr_queue_job_cleanup(job);
	pvr_job_release_pm_ref(job);

	kfree(job->cmd);
	kfree(job);
}

/**
 * pvr_job_put() - Release reference on job
 * @job: Target job.
 */
void
pvr_job_put(struct pvr_job *job)
{
	if (job)
		kref_put(&job->ref_count, pvr_job_release);
}

/**
 * pvr_job_process_stream() - Build job FW structure from stream
 * @pvr_dev: Device pointer.
 * @cmd_defs: Stream definition.
 * @stream: Pointer to command stream.
 * @stream_size: Size of command stream, in bytes.
 * @job: Pointer to job.
 *
 * Caller is responsible for freeing the output structure.
 *
 * Returns:
 *  * 0 on success,
 *  * -%ENOMEM on out of memory, or
 *  * -%EINVAL on malformed stream.
 */
static int
pvr_job_process_stream(struct pvr_device *pvr_dev, const struct pvr_stream_cmd_defs *cmd_defs,
		       void *stream, u32 stream_size, struct pvr_job *job)
{
	int err;

	job->cmd = kzalloc(cmd_defs->dest_size, GFP_KERNEL);
	if (!job->cmd)
		return -ENOMEM;

	job->cmd_len = cmd_defs->dest_size;

	err = pvr_stream_process(pvr_dev, cmd_defs, stream, stream_size, job->cmd);
	if (err)
		kfree(job->cmd);

	return err;
}

static int pvr_fw_cmd_init(struct pvr_device *pvr_dev, struct pvr_job *job,
			   const struct pvr_stream_cmd_defs *stream_def,
			   u64 stream_userptr, u32 stream_len)
{
	void *stream;
	int err;

	stream = memdup_user(u64_to_user_ptr(stream_userptr), stream_len);
	if (IS_ERR(stream))
		return PTR_ERR(stream);

	err = pvr_job_process_stream(pvr_dev, stream_def, stream, stream_len, job);

	kfree(stream);
	return err;
}

static u32
convert_geom_flags(u32 in_flags)
{
	u32 out_flags = 0;

	if (in_flags & DRM_PVR_SUBMIT_JOB_GEOM_CMD_FIRST)
		out_flags |= ROGUE_GEOM_FLAGS_FIRSTKICK;
	if (in_flags & DRM_PVR_SUBMIT_JOB_GEOM_CMD_LAST)
		out_flags |= ROGUE_GEOM_FLAGS_LASTKICK;
	if (in_flags & DRM_PVR_SUBMIT_JOB_GEOM_CMD_SINGLE_CORE)
		out_flags |= ROGUE_GEOM_FLAGS_SINGLE_CORE;

	return out_flags;
}

static u32
convert_frag_flags(u32 in_flags)
{
	u32 out_flags = 0;

	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_SINGLE_CORE)
		out_flags |= ROGUE_FRAG_FLAGS_SINGLE_CORE;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_DEPTHBUFFER)
		out_flags |= ROGUE_FRAG_FLAGS_DEPTHBUFFER;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_STENCILBUFFER)
		out_flags |= ROGUE_FRAG_FLAGS_STENCILBUFFER;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_PREVENT_CDM_OVERLAP)
		out_flags |= ROGUE_FRAG_FLAGS_PREVENT_CDM_OVERLAP;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_SCRATCHBUFFER)
		out_flags |= ROGUE_FRAG_FLAGS_SCRATCHBUFFER;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_GET_VIS_RESULTS)
		out_flags |= ROGUE_FRAG_FLAGS_GET_VIS_RESULTS;
	if (in_flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE)
		out_flags |= ROGUE_FRAG_FLAGS_DISABLE_PIXELMERGE;

	return out_flags;
}

static int
pvr_geom_job_fw_cmd_init(struct pvr_job *job,
			 struct drm_pvr_job *args)
{
	struct rogue_fwif_cmd_geom *cmd;
	int err;

	if (args->flags & ~DRM_PVR_SUBMIT_JOB_GEOM_CMD_FLAGS_MASK)
		return -EINVAL;

	if (job->ctx->type != DRM_PVR_CTX_TYPE_RENDER)
		return -EINVAL;

	if (!job->hwrt)
		return -EINVAL;

	job->fw_ccb_cmd_type = ROGUE_FWIF_CCB_CMD_TYPE_GEOM;
	err = pvr_fw_cmd_init(job->pvr_dev, job, &pvr_cmd_geom_stream,
			      args->cmd_stream, args->cmd_stream_len);
	if (err)
		return err;

	cmd = job->cmd;
	cmd->cmd_shared.cmn.frame_num = 0;
	cmd->flags = convert_geom_flags(args->flags);
	pvr_fw_object_get_fw_addr(job->hwrt->fw_obj, &cmd->cmd_shared.hwrt_data_fw_addr);
	return 0;
}

static int
pvr_frag_job_fw_cmd_init(struct pvr_job *job,
			 struct drm_pvr_job *args)
{
	struct rogue_fwif_cmd_frag *cmd;
	int err;

	if (args->flags & ~DRM_PVR_SUBMIT_JOB_FRAG_CMD_FLAGS_MASK)
		return -EINVAL;

	if (job->ctx->type != DRM_PVR_CTX_TYPE_RENDER)
		return -EINVAL;

	if (!job->hwrt)
		return -EINVAL;

	job->fw_ccb_cmd_type = (args->flags & DRM_PVR_SUBMIT_JOB_FRAG_CMD_PARTIAL_RENDER) ?
			       ROGUE_FWIF_CCB_CMD_TYPE_FRAG_PR :
			       ROGUE_FWIF_CCB_CMD_TYPE_FRAG;
	err = pvr_fw_cmd_init(job->pvr_dev, job, &pvr_cmd_frag_stream,
			      args->cmd_stream, args->cmd_stream_len);
	if (err)
		return err;

	cmd = job->cmd;
	cmd->cmd_shared.cmn.frame_num = 0;
	cmd->flags = convert_frag_flags(args->flags);
	pvr_fw_object_get_fw_addr(job->hwrt->fw_obj, &cmd->cmd_shared.hwrt_data_fw_addr);
	return 0;
}

static u32
convert_compute_flags(u32 in_flags)
{
	u32 out_flags = 0;

	if (in_flags & DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_PREVENT_ALL_OVERLAP)
		out_flags |= ROGUE_COMPUTE_FLAG_PREVENT_ALL_OVERLAP;
	if (in_flags & DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_SINGLE_CORE)
		out_flags |= ROGUE_COMPUTE_FLAG_SINGLE_CORE;

	return out_flags;
}

static int
pvr_compute_job_fw_cmd_init(struct pvr_job *job,
			    struct drm_pvr_job *args)
{
	struct rogue_fwif_cmd_compute *cmd;
	int err;

	if (args->flags & ~DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_FLAGS_MASK)
		return -EINVAL;

	if (job->ctx->type != DRM_PVR_CTX_TYPE_COMPUTE)
		return -EINVAL;

	job->fw_ccb_cmd_type = ROGUE_FWIF_CCB_CMD_TYPE_CDM;
	err = pvr_fw_cmd_init(job->pvr_dev, job, &pvr_cmd_compute_stream,
			      args->cmd_stream, args->cmd_stream_len);
	if (err)
		return err;

	cmd = job->cmd;
	cmd->common.frame_num = 0;
	cmd->flags = convert_compute_flags(args->flags);
	return 0;
}

static u32
convert_transfer_flags(u32 in_flags)
{
	u32 out_flags = 0;

	if (in_flags & DRM_PVR_SUBMIT_JOB_TRANSFER_CMD_SINGLE_CORE)
		out_flags |= ROGUE_TRANSFER_FLAGS_SINGLE_CORE;

	return out_flags;
}

static int
pvr_transfer_job_fw_cmd_init(struct pvr_job *job,
			     struct drm_pvr_job *args)
{
	struct rogue_fwif_cmd_transfer *cmd;
	int err;

	if (args->flags & ~DRM_PVR_SUBMIT_JOB_TRANSFER_CMD_FLAGS_MASK)
		return -EINVAL;

	if (job->ctx->type != DRM_PVR_CTX_TYPE_TRANSFER_FRAG)
		return -EINVAL;

	job->fw_ccb_cmd_type = ROGUE_FWIF_CCB_CMD_TYPE_TQ_3D;
	err = pvr_fw_cmd_init(job->pvr_dev, job, &pvr_cmd_transfer_stream,
			      args->cmd_stream, args->cmd_stream_len);
	if (err)
		return err;

	cmd = job->cmd;
	cmd->common.frame_num = 0;
	cmd->flags = convert_transfer_flags(args->flags);
	return 0;
}

static int
pvr_job_fw_cmd_init(struct pvr_job *job,
		    struct drm_pvr_job *args)
{
	switch (args->type) {
	case DRM_PVR_JOB_TYPE_GEOMETRY:
		return pvr_geom_job_fw_cmd_init(job, args);

	case DRM_PVR_JOB_TYPE_FRAGMENT:
		return pvr_frag_job_fw_cmd_init(job, args);

	case DRM_PVR_JOB_TYPE_COMPUTE:
		return pvr_compute_job_fw_cmd_init(job, args);

	case DRM_PVR_JOB_TYPE_TRANSFER_FRAG:
		return pvr_transfer_job_fw_cmd_init(job, args);

	default:
		return -EINVAL;
	}
}

/**
 * struct pvr_job_data - Helper container for pairing jobs with the
 * sync_ops supplied for them by the user.
 */
struct pvr_job_data {
	/** @job: Pointer to the job. */
	struct pvr_job *job;

	/** @sync_ops: Pointer to the sync_ops associated with @job. */
	struct drm_pvr_sync_op *sync_ops;

	/** @sync_op_count: Number of members of @sync_ops. */
	u32 sync_op_count;
};

/**
 * prepare_job_syncs() - Prepare all sync objects for a single job.
 * @pvr_file: PowerVR file.
 * @job_data: Precreated job and sync_ops array.
 * @signal_array: xarray to receive signal sync objects.
 *
 * Returns:
 *  * 0 on success, or
 *  * Any error code returned by pvr_sync_signal_array_collect_ops(),
 *    pvr_sync_add_deps_to_job(), drm_sched_job_add_resv_dependencies() or
 *    pvr_sync_signal_array_update_fences().
 */
static int
prepare_job_syncs(struct pvr_file *pvr_file,
		  struct pvr_job_data *job_data,
		  struct xarray *signal_array)
{
	struct dma_fence *done_fence;
	int err = pvr_sync_signal_array_collect_ops(signal_array,
						    from_pvr_file(pvr_file),
						    job_data->sync_op_count,
						    job_data->sync_ops);

	if (err)
		return err;

	err = pvr_sync_add_deps_to_job(pvr_file, &job_data->job->base,
				       job_data->sync_op_count,
				       job_data->sync_ops, signal_array);
	if (err)
		return err;

	if (job_data->job->hwrt) {
		/* The geometry job writes the HWRT region headers, which are
		 * then read by the fragment job.
		 */
		struct drm_gem_object *obj =
			gem_from_pvr_gem(job_data->job->hwrt->fw_obj->gem);
		enum dma_resv_usage usage =
			dma_resv_usage_rw(job_data->job->type ==
					  DRM_PVR_JOB_TYPE_GEOMETRY);

		dma_resv_lock(obj->resv, NULL);
		err = drm_sched_job_add_resv_dependencies(&job_data->job->base,
							  obj->resv, usage);
		dma_resv_unlock(obj->resv);
		if (err)
			return err;
	}

	/* We need to arm the job to get the job done fence. */
	done_fence = pvr_queue_job_arm(job_data->job);

	err = pvr_sync_signal_array_update_fences(signal_array,
						  job_data->sync_op_count,
						  job_data->sync_ops,
						  done_fence);
	return err;
}

/**
 * prepare_job_syncs_for_each() - Prepare all sync objects for an array of jobs.
 * @pvr_file: PowerVR file.
 * @job_data: Array of precreated jobs and their sync_ops.
 * @job_count: Number of jobs.
 * @signal_array: xarray to receive signal sync objects.
 *
 * Returns:
 *  * 0 on success, or
 *  * Any error code returned by pvr_vm_bind_job_prepare_syncs().
 */
static int
prepare_job_syncs_for_each(struct pvr_file *pvr_file,
			   struct pvr_job_data *job_data,
			   u32 *job_count,
			   struct xarray *signal_array)
{
	for (u32 i = 0; i < *job_count; i++) {
		int err = prepare_job_syncs(pvr_file, &job_data[i],
					    signal_array);

		if (err) {
			*job_count = i;
			return err;
		}
	}

	return 0;
}

static struct pvr_job *
create_job(struct pvr_device *pvr_dev,
	   struct pvr_file *pvr_file,
	   struct drm_pvr_job *args)
{
	struct pvr_job *job = NULL;
	int err;

	if (!args->cmd_stream || !args->cmd_stream_len)
		return ERR_PTR(-EINVAL);

	if (args->type != DRM_PVR_JOB_TYPE_GEOMETRY &&
	    args->type != DRM_PVR_JOB_TYPE_FRAGMENT &&
	    (args->hwrt.set_handle || args->hwrt.data_index))
		return ERR_PTR(-EINVAL);

	job = kzalloc(sizeof(*job), GFP_KERNEL);
	if (!job)
		return ERR_PTR(-ENOMEM);

	kref_init(&job->ref_count);
	job->type = args->type;
	job->pvr_dev = pvr_dev;

	err = xa_alloc(&pvr_dev->job_ids, &job->id, job, xa_limit_32b, GFP_KERNEL);
	if (err)
		goto err_put_job;

	job->ctx = pvr_context_lookup(pvr_file, args->context_handle);
	if (!job->ctx) {
		err = -EINVAL;
		goto err_put_job;
	}

	if (args->hwrt.set_handle) {
		job->hwrt = pvr_hwrt_data_lookup(pvr_file, args->hwrt.set_handle,
						 args->hwrt.data_index);
		if (!job->hwrt) {
			err = -EINVAL;
			goto err_put_job;
		}
	}

	err = pvr_job_fw_cmd_init(job, args);
	if (err)
		goto err_put_job;

	err = pvr_queue_job_init(job);
	if (err)
		goto err_put_job;

	return job;

err_put_job:
	pvr_job_put(job);
	return ERR_PTR(err);
}

/**
 * pvr_job_data_fini() - Cleanup all allocs used to set up job submission.
 * @job_data: Job data array.
 * @job_count: Number of members of @job_data.
 */
static void
pvr_job_data_fini(struct pvr_job_data *job_data, u32 job_count)
{
	for (u32 i = 0; i < job_count; i++) {
		pvr_job_put(job_data[i].job);
		kvfree(job_data[i].sync_ops);
	}
}

/**
 * pvr_job_data_init() - Init an array of created jobs, associating them with
 * the appropriate sync_ops args, which will be copied in.
 * @pvr_dev: Target PowerVR device.
 * @pvr_file: Pointer to PowerVR file structure.
 * @job_args: Job args array copied from user.
 * @job_count: Number of members of @job_args.
 * @job_data_out: Job data array.
 */
static int pvr_job_data_init(struct pvr_device *pvr_dev,
			     struct pvr_file *pvr_file,
			     struct drm_pvr_job *job_args,
			     u32 *job_count,
			     struct pvr_job_data *job_data_out)
{
	int err = 0, i = 0;

	for (; i < *job_count; i++) {
		job_data_out[i].job =
			create_job(pvr_dev, pvr_file, &job_args[i]);
		err = PTR_ERR_OR_ZERO(job_data_out[i].job);

		if (err) {
			*job_count = i;
			job_data_out[i].job = NULL;
			goto err_cleanup;
		}

		err = PVR_UOBJ_GET_ARRAY(job_data_out[i].sync_ops,
					 &job_args[i].sync_ops);
		if (err) {
			*job_count = i;

			/* Ensure the job created above is also cleaned up. */
			i++;
			goto err_cleanup;
		}

		job_data_out[i].sync_op_count = job_args[i].sync_ops.count;
	}

	return 0;

err_cleanup:
	pvr_job_data_fini(job_data_out, i);

	return err;
}

static void
push_jobs(struct pvr_job_data *job_data, u32 job_count)
{
	for (u32 i = 0; i < job_count; i++)
		pvr_queue_job_push(job_data[i].job);
}

static int
prepare_fw_obj_resv(struct drm_exec *exec, struct pvr_fw_object *fw_obj)
{
	return drm_exec_prepare_obj(exec, gem_from_pvr_gem(fw_obj->gem), 1);
}

static int
jobs_lock_all_objs(struct drm_exec *exec, struct pvr_job_data *job_data,
		   u32 job_count)
{
	for (u32 i = 0; i < job_count; i++) {
		struct pvr_job *job = job_data[i].job;

		/* Grab a lock on a the context, to guard against
		 * concurrent submission to the same queue.
		 */
		int err = drm_exec_lock_obj(exec,
					    gem_from_pvr_gem(job->ctx->fw_obj->gem));

		if (err)
			return err;

		if (job->hwrt) {
			err = prepare_fw_obj_resv(exec,
						  job->hwrt->fw_obj);
			if (err)
				return err;
		}
	}

	return 0;
}

static int
prepare_job_resvs_for_each(struct drm_exec *exec, struct pvr_job_data *job_data,
			   u32 job_count)
{
	drm_exec_until_all_locked(exec) {
		int err = jobs_lock_all_objs(exec, job_data, job_count);

		drm_exec_retry_on_contention(exec);
		if (err)
			return err;
	}

	return 0;
}

static void
update_job_resvs(struct pvr_job *job)
{
	if (job->hwrt) {
		enum dma_resv_usage usage = job->type == DRM_PVR_JOB_TYPE_GEOMETRY ?
					    DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ;
		struct drm_gem_object *obj = gem_from_pvr_gem(job->hwrt->fw_obj->gem);

		dma_resv_add_fence(obj->resv, &job->base.s_fence->finished, usage);
	}
}

static void
update_job_resvs_for_each(struct pvr_job_data *job_data, u32 job_count)
{
	for (u32 i = 0; i < job_count; i++)
		update_job_resvs(job_data[i].job);
}

static bool can_combine_jobs(struct pvr_job *a, struct pvr_job *b)
{
	struct pvr_job *geom_job = a, *frag_job = b;

	/* Geometry and fragment jobs can be combined if they are queued to the
	 * same context and targeting the same HWRT.
	 */
	if (a->type != DRM_PVR_JOB_TYPE_GEOMETRY ||
	    b->type != DRM_PVR_JOB_TYPE_FRAGMENT ||
	    a->ctx != b->ctx ||
	    a->hwrt != b->hwrt)
		return false;

	/* We combine when we see an explicit geom -> frag dep. */
	return drm_sched_job_has_dependency(&frag_job->base,
					    &geom_job->base.s_fence->scheduled);
}

static struct dma_fence *
get_last_queued_job_scheduled_fence(struct pvr_queue *queue,
				    struct pvr_job_data *job_data,
				    u32 cur_job_pos)
{
	/* We iterate over the current job array in reverse order to grab the
	 * last to-be-queued job targeting the same queue.
	 */
	for (u32 i = cur_job_pos; i > 0; i--) {
		struct pvr_job *job = job_data[i - 1].job;

		if (job->ctx == queue->ctx && job->type == queue->type)
			return dma_fence_get(&job->base.s_fence->scheduled);
	}

	/* If we didn't find any, we just return the last queued job scheduled
	 * fence attached to the queue.
	 */
	return dma_fence_get(queue->last_queued_job_scheduled_fence);
}

static int
pvr_jobs_link_geom_frag(struct pvr_job_data *job_data, u32 *job_count)
{
	for (u32 i = 0; i < *job_count - 1; i++) {
		struct pvr_job *geom_job = job_data[i].job;
		struct pvr_job *frag_job = job_data[i + 1].job;
		struct pvr_queue *frag_queue;
		struct dma_fence *f;

		if (!can_combine_jobs(job_data[i].job, job_data[i + 1].job))
			continue;

		/* The fragment job will be submitted by the geometry queue. We
		 * need to make sure it comes after all the other fragment jobs
		 * queued before it.
		 */
		frag_queue = pvr_context_get_queue_for_job(frag_job->ctx,
							   frag_job->type);
		f = get_last_queued_job_scheduled_fence(frag_queue, job_data,
							i);
		if (f) {
			int err = drm_sched_job_add_dependency(&geom_job->base,
							       f);
			if (err) {
				*job_count = i;
				return err;
			}
		}

		/* The KCCB slot will be reserved by the geometry job, so we can
		 * drop the KCCB fence on the fragment job.
		 */
		pvr_kccb_fence_put(frag_job->kccb_fence);
		frag_job->kccb_fence = NULL;

		geom_job->paired_job = frag_job;
		frag_job->paired_job = geom_job;

		/* Skip the fragment job we just paired to the geometry job. */
		i++;
	}

	return 0;
}

/**
 * pvr_submit_jobs() - Submit jobs to the GPU
 * @pvr_dev: Target PowerVR device.
 * @pvr_file: Pointer to PowerVR file structure.
 * @args: Ioctl args.
 *
 * This initial implementation is entirely synchronous; on return the GPU will
 * be idle. This will not be the case for future implementations.
 *
 * Returns:
 *  * 0 on success,
 *  * -%EFAULT if arguments can not be copied from user space, or
 *  * -%EINVAL on invalid arguments, or
 *  * Any other error.
 */
int
pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file,
		struct drm_pvr_ioctl_submit_jobs_args *args)
{
	struct pvr_job_data *job_data = NULL;
	struct drm_pvr_job *job_args;
	struct xarray signal_array;
	u32 jobs_alloced = 0;
	struct drm_exec exec;
	int err;

	if (!args->jobs.count)
		return -EINVAL;

	err = PVR_UOBJ_GET_ARRAY(job_args, &args->jobs);
	if (err)
		return err;

	job_data = kvmalloc_array(args->jobs.count, sizeof(*job_data),
				  GFP_KERNEL | __GFP_ZERO);
	if (!job_data) {
		err = -ENOMEM;
		goto out_free;
	}

	err = pvr_job_data_init(pvr_dev, pvr_file, job_args, &args->jobs.count,
				job_data);
	if (err)
		goto out_free;

	jobs_alloced = args->jobs.count;

	/*
	 * Flush MMU if needed - this has been deferred until now to avoid
	 * overuse of this expensive operation.
	 */
	err = pvr_mmu_flush_exec(pvr_dev, false);
	if (err)
		goto out_job_data_cleanup;

	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES, 0);

	xa_init_flags(&signal_array, XA_FLAGS_ALLOC);

	err = prepare_job_syncs_for_each(pvr_file, job_data, &args->jobs.count,
					 &signal_array);
	if (err)
		goto out_exec_fini;

	err = prepare_job_resvs_for_each(&exec, job_data, args->jobs.count);
	if (err)
		goto out_exec_fini;

	err = pvr_jobs_link_geom_frag(job_data, &args->jobs.count);
	if (err)
		goto out_exec_fini;

	/* Anything after that point must succeed because we start exposing job
	 * finished fences to the outside world.
	 */
	update_job_resvs_for_each(job_data, args->jobs.count);
	push_jobs(job_data, args->jobs.count);
	pvr_sync_signal_array_push_fences(&signal_array);
	err = 0;

out_exec_fini:
	drm_exec_fini(&exec);
	pvr_sync_signal_array_cleanup(&signal_array);

out_job_data_cleanup:
	pvr_job_data_fini(job_data, jobs_alloced);

out_free:
	kvfree(job_data);
	kvfree(job_args);

	return err;
}
