mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
Now that the run queue to scheduler relationship is always 1:1 we can embed it (the run queue) directly in the scheduler struct and save on some allocation error handling code and such. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Cc: Christian König <christian.koenig@amd.com> Cc: Danilo Krummrich <dakr@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <phasta@kernel.org> Acked-by: Danilo Krummrich <dakr@kernel.org> Tested-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Signed-off-by: Philipp Stanner <phasta@kernel.org> Link: https://patch.msgid.link/20260417103744.76020-15-tvrtko.ursulin@igalia.com
146 lines
4.1 KiB
C
146 lines
4.1 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
|
|
#ifndef _DRM_GPU_SCHEDULER_INTERNAL_H_
|
|
#define _DRM_GPU_SCHEDULER_INTERNAL_H_
|
|
|
|
#include <linux/ktime.h>
|
|
#include <linux/kref.h>
|
|
#include <linux/spinlock.h>
|
|
|
|
/**
|
|
* struct drm_sched_entity_stats - execution stats for an entity.
|
|
* @kref: reference count for the object.
|
|
* @lock: lock guarding the @runtime updates.
|
|
* @runtime: time entity spent on the GPU.
|
|
* @prev_runtime: previous @runtime used to get the runtime delta.
|
|
* @vruntime: virtual runtime as accumulated by the fair algorithm.
|
|
* @avg_job_us: average job duration.
|
|
*
|
|
* Because jobs and entities have decoupled lifetimes, ie. we cannot access the
|
|
* entity once the job has been de-queued, and we do need know how much GPU time
|
|
* each entity has spent, we need to track this in a separate object which is
|
|
* reference counted by both entities and jobs.
|
|
*/
|
|
struct drm_sched_entity_stats {
|
|
struct kref kref;
|
|
spinlock_t lock; /* Protects the below fields. */
|
|
ktime_t runtime;
|
|
ktime_t prev_runtime;
|
|
ktime_t vruntime;
|
|
|
|
struct ewma_drm_sched_avgtime avg_job_us;
|
|
};
|
|
|
|
bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
|
|
struct drm_sched_entity *entity);
|
|
void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
|
|
|
|
void drm_sched_rq_init(struct drm_sched_rq *rq);
|
|
|
|
struct drm_gpu_scheduler *
|
|
drm_sched_rq_add_entity(struct drm_sched_entity *entity);
|
|
void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
|
|
struct drm_sched_entity *entity);
|
|
void drm_sched_rq_pop_entity(struct drm_sched_entity *entity);
|
|
|
|
struct drm_sched_entity *
|
|
drm_sched_select_entity(struct drm_gpu_scheduler *sched);
|
|
|
|
void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
|
|
struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
|
|
|
|
struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *s_entity,
|
|
void *owner, u64 drm_client_id);
|
|
void drm_sched_fence_init(struct drm_sched_fence *fence,
|
|
struct drm_sched_entity *entity);
|
|
void drm_sched_fence_free(struct drm_sched_fence *fence);
|
|
|
|
void drm_sched_fence_scheduled(struct drm_sched_fence *fence,
|
|
struct dma_fence *parent);
|
|
void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
|
|
|
|
/**
|
|
* drm_sched_entity_queue_pop - Low level helper for popping queued jobs
|
|
*
|
|
* @entity: scheduler entity
|
|
*
|
|
* Low level helper for popping queued jobs.
|
|
*
|
|
* Returns: The job dequeued or NULL.
|
|
*/
|
|
static inline struct drm_sched_job *
|
|
drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
|
|
{
|
|
struct spsc_node *node;
|
|
|
|
node = spsc_queue_pop(&entity->job_queue);
|
|
if (!node)
|
|
return NULL;
|
|
|
|
return container_of(node, struct drm_sched_job, queue_node);
|
|
}
|
|
|
|
/**
|
|
* drm_sched_entity_queue_peek - Low level helper for peeking at the job queue
|
|
*
|
|
* @entity: scheduler entity
|
|
*
|
|
* Low level helper for peeking at the job queue
|
|
*
|
|
* Returns: The job at the head of the queue or NULL.
|
|
*/
|
|
static inline struct drm_sched_job *
|
|
drm_sched_entity_queue_peek(struct drm_sched_entity *entity)
|
|
{
|
|
struct spsc_node *node;
|
|
|
|
node = spsc_queue_peek(&entity->job_queue);
|
|
if (!node)
|
|
return NULL;
|
|
|
|
return container_of(node, struct drm_sched_job, queue_node);
|
|
}
|
|
|
|
/* Return true if entity could provide a job. */
|
|
static inline bool
|
|
drm_sched_entity_is_ready(struct drm_sched_entity *entity)
|
|
{
|
|
if (!spsc_queue_count(&entity->job_queue))
|
|
return false;
|
|
|
|
if (READ_ONCE(entity->dependency))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void drm_sched_entity_stats_release(struct kref *kref);
|
|
|
|
/**
|
|
* drm_sched_entity_stats_get - Obtain a reference count on &struct drm_sched_entity_stats object
|
|
* @stats: struct drm_sched_entity_stats pointer
|
|
*
|
|
* Return: struct drm_sched_entity_stats pointer
|
|
*/
|
|
static inline struct drm_sched_entity_stats *
|
|
drm_sched_entity_stats_get(struct drm_sched_entity_stats *stats)
|
|
{
|
|
kref_get(&stats->kref);
|
|
|
|
return stats;
|
|
}
|
|
|
|
/**
|
|
* drm_sched_entity_stats_put - Release a reference count on &struct drm_sched_entity_stats object
|
|
* @stats: struct drm_sched_entity_stats pointer
|
|
*/
|
|
static inline void
|
|
drm_sched_entity_stats_put(struct drm_sched_entity_stats *stats)
|
|
{
|
|
kref_put(&stats->kref, drm_sched_entity_stats_release);
|
|
}
|
|
|
|
ktime_t drm_sched_entity_stats_job_add_gpu_time(struct drm_sched_job *job);
|
|
|
|
#endif
|