Re: [PATCH v5 14/17] drm/imagination: Implement job submission and scheduling

From: Jann Horn
Date: Thu Aug 17 2023 - 18:43:48 EST


On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker <sarah.walker@xxxxxxxxxx> wrote:
> Implement job submission ioctl. Job scheduling is implemented using
> drm_sched.
[...]
> +/**
> + * 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;

I think this bailout looks fine...

> + }
> +
> + err = PVR_UOBJ_GET_ARRAY(job_data_out[i].sync_ops,
> + &job_args[i].sync_ops);
> + if (err) {
> + *job_count = i;
> + goto err_cleanup;

... but this bailout looks like it has an off-by-one. We have
initialized the job pointers up to (inclusive) index i...

> + }
> +
> + 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);

... but then we pass i to pvr_job_data_fini() as the exclusive limit
of job indices to free? I think this will leave a leaked job around.


> +
> + return err;
> +}