[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAG48ez3_ye3jp9Aqn5yi+bjVGWvCJt89TSLW1EOgX_RisXYNBA@mail.gmail.com>
Date: Fri, 18 Aug 2023 00:42:21 +0200
From: Jann Horn <jannh@...gle.com>
To: Sarah Walker <sarah.walker@...tec.com>
Cc: dri-devel@...ts.freedesktop.org, matthew.brost@...el.com,
luben.tuikov@....com, tzimmermann@...e.de,
linux-kernel@...r.kernel.org, mripard@...nel.org, afd@...com,
boris.brezillon@...labora.com, dakr@...hat.com,
donald.robson@...tec.com, hns@...delico.com,
christian.koenig@....com, faith.ekstrand@...labora.com
Subject: Re: [PATCH v5 14/17] drm/imagination: Implement job submission and scheduling
On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker <sarah.walker@...tec.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;
> +}
Powered by blists - more mailing lists