#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"
struct xe_dep_scheduler {
struct drm_gpu_scheduler sched;
struct drm_sched_entity entity;
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,
};
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,
.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);
}
void xe_dep_scheduler_fini(struct xe_dep_scheduler *dep_scheduler)
{
drm_sched_entity_fini(&dep_scheduler->entity);
drm_sched_fini(&dep_scheduler->sched);
kfree_rcu(dep_scheduler, rcu);
}
struct drm_sched_entity *
xe_dep_scheduler_entity(struct xe_dep_scheduler *dep_scheduler)
{
return &dep_scheduler->entity;
}