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

Jann Horn jannh at google.com
Thu Aug 17 22:42:21 UTC 2023


On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker <sarah.walker at imgtec.com> 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;
> +}


More information about the dri-devel mailing list