mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
144 lines
3.8 KiB
C
144 lines
3.8 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright © 2025 Intel Corporation
|
|
*/
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <drm/gpu_scheduler.h>
|
|
|
|
#include "xe_dep_job_types.h"
|
|
#include "xe_dep_scheduler.h"
|
|
#include "xe_device_types.h"
|
|
|
|
/**
|
|
* DOC: Xe Dependency Scheduler
|
|
*
|
|
* The Xe dependency scheduler is a simple wrapper built around the DRM
|
|
* scheduler to execute jobs once their dependencies are resolved (i.e., all
|
|
* input fences specified as dependencies are signaled). The jobs that are
|
|
* executed contain virtual functions to run (execute) and free the job,
|
|
* allowing a single dependency scheduler to handle jobs performing different
|
|
* operations.
|
|
*
|
|
* Example use cases include deferred resource freeing, TLB invalidations after
|
|
* bind jobs, etc.
|
|
*/
|
|
|
|
/** struct xe_dep_scheduler - Generic Xe dependency scheduler */
|
|
struct xe_dep_scheduler {
|
|
/** @sched: DRM GPU scheduler */
|
|
struct drm_gpu_scheduler sched;
|
|
/** @entity: DRM scheduler entity */
|
|
struct drm_sched_entity entity;
|
|
/** @rcu: For safe freeing of exported dma fences */
|
|
struct rcu_head rcu;
|
|
};
|
|
|
|
static struct dma_fence *xe_dep_scheduler_run_job(struct drm_sched_job *drm_job)
|
|
{
|
|
struct xe_dep_job *dep_job =
|
|
container_of(drm_job, typeof(*dep_job), drm);
|
|
|
|
return dep_job->ops->run_job(dep_job);
|
|
}
|
|
|
|
static void xe_dep_scheduler_free_job(struct drm_sched_job *drm_job)
|
|
{
|
|
struct xe_dep_job *dep_job =
|
|
container_of(drm_job, typeof(*dep_job), drm);
|
|
|
|
dep_job->ops->free_job(dep_job);
|
|
}
|
|
|
|
static const struct drm_sched_backend_ops sched_ops = {
|
|
.run_job = xe_dep_scheduler_run_job,
|
|
.free_job = xe_dep_scheduler_free_job,
|
|
};
|
|
|
|
/**
|
|
* xe_dep_scheduler_create() - Generic Xe dependency scheduler create
|
|
* @xe: Xe device
|
|
* @submit_wq: Submit workqueue struct (can be NULL)
|
|
* @name: Name of dependency scheduler
|
|
* @job_limit: Max dependency jobs that can be scheduled
|
|
*
|
|
* Create a generic Xe dependency scheduler and initialize internal DRM
|
|
* scheduler objects.
|
|
*
|
|
* Return: Generic Xe dependency scheduler object on success, ERR_PTR failure
|
|
*/
|
|
struct xe_dep_scheduler *
|
|
xe_dep_scheduler_create(struct xe_device *xe,
|
|
struct workqueue_struct *submit_wq,
|
|
const char *name, u32 job_limit)
|
|
{
|
|
struct xe_dep_scheduler *dep_scheduler;
|
|
struct drm_gpu_scheduler *sched;
|
|
const struct drm_sched_init_args args = {
|
|
.ops = &sched_ops,
|
|
.submit_wq = submit_wq,
|
|
.num_rqs = 1,
|
|
.credit_limit = job_limit,
|
|
.timeout = MAX_SCHEDULE_TIMEOUT,
|
|
.name = name,
|
|
.dev = xe->drm.dev,
|
|
};
|
|
int err;
|
|
|
|
dep_scheduler = kzalloc_obj(*dep_scheduler);
|
|
if (!dep_scheduler)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
err = drm_sched_init(&dep_scheduler->sched, &args);
|
|
if (err)
|
|
goto err_free;
|
|
|
|
sched = &dep_scheduler->sched;
|
|
err = drm_sched_entity_init(&dep_scheduler->entity, 0, &sched, 1, NULL);
|
|
if (err)
|
|
goto err_sched;
|
|
|
|
init_rcu_head(&dep_scheduler->rcu);
|
|
|
|
return dep_scheduler;
|
|
|
|
err_sched:
|
|
drm_sched_fini(&dep_scheduler->sched);
|
|
err_free:
|
|
kfree(dep_scheduler);
|
|
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
/**
|
|
* xe_dep_scheduler_fini() - Generic Xe dependency scheduler finalize
|
|
* @dep_scheduler: Generic Xe dependency scheduler object
|
|
*
|
|
* Finalize internal DRM scheduler objects and free generic Xe dependency
|
|
* scheduler object
|
|
*/
|
|
void xe_dep_scheduler_fini(struct xe_dep_scheduler *dep_scheduler)
|
|
{
|
|
drm_sched_entity_fini(&dep_scheduler->entity);
|
|
drm_sched_fini(&dep_scheduler->sched);
|
|
/*
|
|
* RCU free due sched being exported via DRM scheduler fences
|
|
* (timeline name).
|
|
*/
|
|
kfree_rcu(dep_scheduler, rcu);
|
|
}
|
|
|
|
/**
|
|
* xe_dep_scheduler_entity() - Retrieve a generic Xe dependency scheduler
|
|
* DRM scheduler entity
|
|
* @dep_scheduler: Generic Xe dependency scheduler object
|
|
*
|
|
* Return: The generic Xe dependency scheduler's DRM scheduler entity
|
|
*/
|
|
struct drm_sched_entity *
|
|
xe_dep_scheduler_entity(struct xe_dep_scheduler *dep_scheduler)
|
|
{
|
|
return &dep_scheduler->entity;
|
|
}
|