drm/v3d: Add a CPU job submission

Create a new type of job, a CPU job. A CPU job is a type of job that
performs operations that requires CPU intervention. The overall idea is
to use user extensions to enable different types of CPU job, allowing the
CPU job to perform different operations according to the type of user
extension. The user extension ID identify the type of CPU job that must
be dealt.

Having a CPU job is interesting for synchronization purposes as a CPU
job has a queue like any other V3D job and can be synchoronized by the
multisync extension.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Co-developed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231130164420.932823-9-mcanal@igalia.com
This commit is contained in:
Melissa Wen
2023-11-30 13:40:30 -03:00
committed by Maíra Canal
parent 464c61e76d
commit aafc1a2bea
5 changed files with 179 additions and 1 deletions

View File

@@ -772,3 +772,89 @@ fail:
return ret;
}
static const unsigned int cpu_job_bo_handle_count[] = { };
/**
* v3d_submit_cpu_ioctl() - Submits a CPU job to the V3D.
* @dev: DRM device
* @data: ioctl argument
* @file_priv: DRM file for this fd
*
* Userspace specifies the CPU job type and data required to perform its
* operations through the drm_v3d_extension struct.
*/
int
v3d_submit_cpu_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct v3d_dev *v3d = to_v3d_dev(dev);
struct drm_v3d_submit_cpu *args = data;
struct v3d_submit_ext se = {0};
struct v3d_cpu_job *cpu_job = NULL;
struct ww_acquire_ctx acquire_ctx;
int ret;
if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) {
DRM_INFO("Invalid flags: %d\n", args->flags);
return -EINVAL;
}
ret = v3d_job_allocate((void *)&cpu_job, sizeof(*cpu_job));
if (ret)
return ret;
if (args->flags & DRM_V3D_SUBMIT_EXTENSION) {
ret = v3d_get_extensions(file_priv, args->extensions, &se);
if (ret) {
DRM_DEBUG("Failed to get extensions.\n");
goto fail;
}
}
/* Every CPU job must have a CPU job user extension */
if (!cpu_job->job_type) {
DRM_DEBUG("CPU job must have a CPU job user extension.\n");
goto fail;
}
if (args->bo_handle_count != cpu_job_bo_handle_count[cpu_job->job_type]) {
DRM_DEBUG("This CPU job was not submitted with the proper number of BOs.\n");
goto fail;
}
ret = v3d_job_init(v3d, file_priv, &cpu_job->base,
v3d_job_free, 0, &se, V3D_CPU);
if (ret)
goto fail;
if (args->bo_handle_count) {
ret = v3d_lookup_bos(dev, file_priv, &cpu_job->base,
args->bo_handles, args->bo_handle_count);
if (ret)
goto fail;
ret = v3d_lock_bo_reservations(&cpu_job->base, &acquire_ctx);
if (ret)
goto fail;
}
mutex_lock(&v3d->sched_lock);
v3d_push_job(&cpu_job->base);
mutex_unlock(&v3d->sched_lock);
v3d_attach_fences_and_unlock_reservation(file_priv,
&cpu_job->base,
&acquire_ctx, 0,
NULL, cpu_job->base.done_fence);
v3d_job_put(&cpu_job->base);
return 0;
fail:
v3d_job_cleanup((void *)cpu_job);
v3d_put_multisync_post_deps(&se);
return ret;
}